[Koha-patches] [PATCH 34/54] Circulation rules management : everything (issues, holds, fines) now at granular level

Mike Hafen mdhafen at tech.washk12.org
Thu Dec 16 18:21:22 CET 2010


Looks like the remains of a merge conflict.  Better fix that.

in C4/Reserves.pm

+>>>>>>> [MT2355] Ergonomy improvement in smart rule management


On Thu, Dec 16, 2010 at 3:54 AM, <paul.poulain at biblibre.com> wrote:

> From: Paul Poulain <paul.poulain at biblibre.com>
>
> All scripts = there are some (a few) reindenting changes.
>
> * C4/IssuintRules.pm
>  script created : contains all circ rules related functions
>
> * C4/Circulation.pm
> - rewrite issuing rules according to new behaviour : default values applies
> as default, not as total. There is also an inheritance, meaning you don't
> have to define all rules
> - debarment management : debarred patrons now can have a limit date of
> debarment (for fine in days, but also for a limited debarrment)
> - lot of lines removes (now in IssuinRules.pm)
> - modifys the offline circ : works in conjunction with the Firefox plugin.
> All offline circ code is in another patch
>
> * C4/Overdues.pm
> - use IssuingRules.pm functions
> - deal with debarment up to a givendate
>
> * C4/Reserves.pm
> - deal with HoldRules at granular level. The library can now define rules
> for hold at ccode(itype) / branch / patron category level
> - added a pickupDelay
>
> * admin/smart-rules.pl
> - script rewritten
> - added ajax (smart-rules-service) to modify a cell directly
>
> * admin/branch_transfer_limits.pl
> - some variable renamed for more readability
>
> * circ/branchtransfers.pl
> - ModReserveAffect now deals with branches to check hold rules
>
> * circ/circulation.pl and circ/returns.pl
> - deals with debardate where applicable
> - deals with possible holds on a given item adapted to fit new hold rules
> - display borrower relatives issues (on circulation.pl only)
>
> * reserve/modrequest.pl, placerequest.pl, renewscript.pl and request.pl
> - deals with new granular-level hold rules
>
> * unit tests for Circulation.pm, GetMemberDetails.pm and Overdues.pm
> - deals with IssuingRules.pm package & API changes
>
> * opac-reserve.pl and opac-modrequest:
> - deals with holds at granular level
> ---
>  C4/Circulation.pm                                  |  918
> +++++++++-----------
>  C4/IssuingRules.pm                                 |  261 ++++++
>  C4/Overdues.pm                                     |   81 +--
>  C4/Reserves.pm                                     |  631 ++++++++++----
>  admin/branch_transfer_limits.pl                    |   22 +-
>  admin/smart-rules-service.pl                       |   59 ++
>  admin/smart-rules.pl                               |  567 +++----------
>  circ/branchtransfers.pl                            |    4 +-
>  circ/circulation.pl                                |  282 +++++--
>  circ/returns.pl                                    |  137 +++-
>  .../en/modules/admin/branch_transfer_limits.tmpl   |   15 +-
>  .../prog/en/modules/admin/clone-rules.tmpl         |    3 +-
>  .../prog/en/modules/admin/smart-rules.tmpl         |  589 +++++++------
>  .../prog/en/modules/circ/circulation.tmpl          |  441 ++++++----
>  .../prog/en/modules/circ/returns.tmpl              |  151 ++--
>  .../prog/en/modules/reserve/request.tmpl           |   30 +-
>  .../opac-tmpl/prog/en/modules/opac-reserve.tmpl    |   53 +-
>  opac/opac-modrequest.pl                            |    4 +-
>  opac/opac-reserve.pl                               |   68 +-
>  reserve/modrequest.pl                              |   19 +-
>  reserve/placerequest.pl                            |   92 +-
>  reserve/renewscript.pl                             |   57 ++-
>  reserve/request.pl                                 |   48 +-
>  t/lib/KohaTest/Circulation.pm                      |    2 -
>  t/lib/KohaTest/Members/GetMemberDetails.pm         |    6 +-
>  t/lib/KohaTest/Overdues.pm                         |    1 -
>  26 files changed, 2608 insertions(+), 1933 deletions(-)
>  create mode 100644 C4/IssuingRules.pm
>  create mode 100755 admin/smart-rules-service.pl
>
> diff --git a/C4/Circulation.pm b/C4/Circulation.pm
> index 0131e90..08b2a0b 100644
> --- a/C4/Circulation.pm
> +++ b/C4/Circulation.pm
> @@ -27,12 +27,15 @@ use C4::Koha;
>  use C4::Biblio;
>  use C4::Items;
>  use C4::Members;
> -use C4::Dates;
> +use C4::IssuingRules;
> +use C4::Dates qw/format_date/;
>  use C4::Calendar;
>  use C4::Accounts;
> +use C4::Overdues ;
>  use C4::ItemCirculationAlertPreference;
>  use C4::Message;
>  use C4::Debug;
> +use YAML;
>  use Date::Calc qw(
>   Today
>   Today_and_Now
> @@ -41,6 +44,9 @@ use Date::Calc qw(
>   Date_to_Days
>   Day_of_Week
>   Add_Delta_Days
> +  Delta_Days
> +  check_date
> +  Add_Delta_Days
>  );
>  use POSIX qw(strftime);
>  use C4::Branch; # GetBranches
> @@ -72,9 +78,6 @@ BEGIN {
>                &GetItemIssues
>                &GetBorrowerIssues
>                &GetIssuingCharges
> -               &GetIssuingRule
> -        &GetBranchBorrowerCircRule
> -        &GetBranchItemRule
>                &GetBiblioIssues
>                &GetOpenIssue
>                &AnonymiseIssueHistory
> @@ -97,6 +100,15 @@ BEGIN {
>                 &CreateBranchTransferLimit
>                 &DeleteBranchTransferLimits
>        );
> +
> +       # subs to deal with offline circulation
> +       push @EXPORT, qw(
> +      &GetOfflineOperations
> +               &GetOfflineOperation
> +               &AddOfflineOperation
> +               &DeleteOfflineOperation
> +               &ProcessOfflineOperation
> +       );
>  }
>
>  =head1 NAME
> @@ -345,116 +357,97 @@ sub TooMany {
>        my $item                = shift;
>     my $cat_borrower    = $borrower->{'categorycode'};
>     my $dbh             = C4::Context->dbh;
> -       my $branch;
> +       my $exactbranch;
>        # Get which branchcode we need
> -       $branch = _GetCircControlBranch($item,$borrower);
> -       my $type = (C4::Context->preference('item-level_itypes'))
> +       $exactbranch = _GetCircControlBranch($item,$borrower);
> +       my $itype = (C4::Context->preference('item-level_itypes'))
>                        ? $item->{'itype'}         # item-level
>                        : $item->{'itemtype'};     # biblio-level
>
>     # given branch, patron category, and item type, determine
>     # applicable issuing rule
> -    my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch);
> -
> -    # if a rule is found and has a loan limit set, count
> -    # how many loans the patron already has that meet that
> -    # rule
> -    if (defined($issuing_rule) and
> defined($issuing_rule->{'maxissueqty'})) {
> -        my @bind_params;
> -        my $count_query = "SELECT COUNT(*) FROM issues
> -                           JOIN items USING (itemnumber) ";
> -
> -        my $rule_itemtype = $issuing_rule->{itemtype};
> -        if ($rule_itemtype eq "*") {
> -            # matching rule has the default item type, so count only
> -            # those existing loans that don't fall under a more
> -            # specific rule
> -            if (C4::Context->preference('item-level_itypes')) {
> -                $count_query .= " WHERE items.itype NOT IN (
> -                                    SELECT itemtype FROM issuingrules
> -                                    WHERE branchcode = ?
> -                                    AND   (categorycode = ? OR
> categorycode = ?)
> -                                    AND   itemtype <> '*'
> -                                  ) ";
> -            } else {
> -                $count_query .= " JOIN  biblioitems USING (biblionumber)
> -                                  WHERE biblioitems.itemtype NOT IN (
> -                                    SELECT itemtype FROM issuingrules
> -                                    WHERE branchcode = ?
> -                                    AND   (categorycode = ? OR
> categorycode = ?)
> -                                    AND   itemtype <> '*'
> -                                  ) ";
> -            }
> -            push @bind_params, $issuing_rule->{branchcode};
> -            push @bind_params, $issuing_rule->{categorycode};
> -            push @bind_params, $cat_borrower;
> -        } else {
> -            # rule has specific item type, so count loans of that
> -            # specific item type
> -            if (C4::Context->preference('item-level_itypes')) {
> -                $count_query .= " WHERE items.itype = ? ";
> -            } else {
> -                $count_query .= " JOIN  biblioitems USING (biblionumber)
> -                                  WHERE biblioitems.itemtype= ? ";
> -            }
> -            push @bind_params, $type;
> -        }
> -
> -        $count_query .= " AND borrowernumber = ? ";
> -        push @bind_params, $borrower->{'borrowernumber'};
> -        my $rule_branch = $issuing_rule->{branchcode};
> -        if ($rule_branch ne "*") {
> -            if (C4::Context->preference('CircControl') eq 'PickupLibrary')
> {
> -                $count_query .= " AND issues.branchcode = ? ";
> -                push @bind_params, $branch;
> -            } elsif (C4::Context->preference('CircControl') eq
> 'PatronLibrary') {
> -                ; # if branch is the patron's home branch, then count all
> loans by patron
> -            } else {
> -                $count_query .= " AND items.homebranch = ? ";
> -                push @bind_params, $branch;
> -            }
> -        }
> -
> -        my $count_sth = $dbh->prepare($count_query);
> -        $count_sth->execute(@bind_params);
> -        my ($current_loan_count) = $count_sth->fetchrow_array;
> +    my $branchfield = C4::Context->Preference('HomeOrHoldingBranch') ||
> "homebranch";
> +    #By default, Patron is supposed not to be able to borrow
> +    my $toomany = 1;
> +
> +    foreach my $branch ( $exactbranch, '*' ) {
> +        foreach my $type ( $itype, '*' ) {
> +            my $issuing_rule = GetIssuingRule( $cat_borrower, $type,
> $branch );
> +
> +            # if a rule is found and has a loan limit set, count
> +            # how many loans the patron already has that meet that
> +            # rule
> +            if ( defined($issuing_rule) and defined(
> $issuing_rule->{'maxissueqty'} ) ) {
> +                my @bind_params;
> +                my $count_query = "SELECT COUNT(*) FROM issues
> +                                   JOIN items USING (itemnumber) ";
> +
> +                my $rule_itemtype = $issuing_rule->{itemtype};
> +                if ($rule_itemtype eq "*") {
> +                    # matching rule has the default item type, so count
> all the items issued for that branch no
> +                    # those existing loans that don't fall under a more
> +                    # specific rule Not QUITE
> +                    if (C4::Context->preference('item-level_itypes')) {
> +                        $count_query .= " WHERE items.itype NOT IN (
> +                                                SELECT itemtype FROM
> issuingrules
> +                                                WHERE branchcode = ?
> +                                                AND   (categorycode = ? OR
> categorycode = ?)
> +                                                AND   itemtype <> '*'
> +                                           )";
> +                    } else {
> +                        $count_query .= " JOIN  biblioitems USING
> (biblionumber)
> +                                            WHERE biblioitems.itemtype NOT
> IN (
> +                                                SELECT itemtype FROM
> issuingrules
> +                                                WHERE branchcode = ?
> +                                                AND   (categorycode = ? OR
> categorycode = ?)
> +                                                AND   itemtype <> '*'
> +                                           )";
> +                    }
> +                    push @bind_params, $issuing_rule->{branchcode};
> +                    push @bind_params, $issuing_rule->{categorycode};
> +                    push @bind_params, $cat_borrower;
> +                } else {
> +                    # rule has specific item type, so count loans of that
> +                    # specific item type
> +                    if (C4::Context->preference('item-level_itypes')) {
> +                        $count_query .= " WHERE items.itype = ? ";
> +                    } else {
> +                        $count_query .= " JOIN  biblioitems USING
> (biblionumber)
> +                                      WHERE biblioitems.itemtype= ? ";
> +                    }
> +                    push @bind_params, $type;
> +                }
>
> -        my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
> -        if ($current_loan_count >= $max_loans_allowed) {
> -            return "$current_loan_count / $max_loans_allowed";
> -        }
> -    }
> +                $count_query .= " AND borrowernumber = ? ";
> +                push @bind_params, $borrower->{'borrowernumber'};
> +                my $rule_branch = $issuing_rule->{branchcode};
> +                if ( $rule_branch ne "*" ) {
> +                    if ( C4::Context->preference('CircControl') eq
> 'PickupLibrary' ) {
> +                        $count_query .= " AND issues.branchcode = ? ";
> +                        push @bind_params, $branch;
> +                    } elsif ( C4::Context->preference('CircControl') eq
> 'PatronLibrary' ) {
> +                        ;    # if branch is the patron's home branch, then
> count all loans by patron
> +                    } else {
> +                        $count_query .= " AND items.$branchfield = ? ";
> +                        push @bind_params, $branch;
> +                    }
> +                }
>
> -    # Now count total loans against the limit for the branch
> -    my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch,
> $cat_borrower);
> -    if (defined($branch_borrower_circ_rule->{maxissueqty})) {
> -        my @bind_params = ();
> -        my $branch_count_query = "SELECT COUNT(*) FROM issues
> -                                  JOIN items USING (itemnumber)
> -                                  WHERE borrowernumber = ? ";
> -        push @bind_params, $borrower->{borrowernumber};
> -
> -        if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
> -            $branch_count_query .= " AND issues.branchcode = ? ";
> -            push @bind_params, $branch;
> -        } elsif (C4::Context->preference('CircControl') eq
> 'PatronLibrary') {
> -            ; # if branch is the patron's home branch, then count all
> loans by patron
> -        } else {
> -            $branch_count_query .= " AND items.homebranch = ? ";
> -            push @bind_params, $branch;
> -        }
> -        my $branch_count_sth = $dbh->prepare($branch_count_query);
> -        $branch_count_sth->execute(@bind_params);
> -        my ($current_loan_count) = $branch_count_sth->fetchrow_array;
> +                my $count_sth = $dbh->prepare($count_query);
> +                $count_sth->execute(@bind_params);
> +                my ($current_loan_count) = $count_sth->fetchrow_array;
>
> -        my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty};
> -        if ($current_loan_count >= $max_loans_allowed) {
> -            return "$current_loan_count / $max_loans_allowed";
> +                my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
> +                if ( $current_loan_count >= $max_loans_allowed ) {
> +                    return 1,$current_loan_count,$max_loans_allowed;
> +                }
> +                else {
> +                    $toomany=0;
> +                }
> +            }
>         }
>     }
> -
> -    # OK, the patron can issue !!!
> -    return;
> +    return $toomany;
>  }
>
>  =head2 itemissues
> @@ -683,7 +676,10 @@ sub CanBookBeIssued {
>         my $branch = _GetCircControlBranch($item,$borrower);
>         my $itype = ( C4::Context->preference('item-level_itypes') ) ?
> $item->{'itype'} : $biblioitem->{'itemtype'};
>         my $loanlength = GetLoanLength( $borrower->{'categorycode'},
> $itype, $branch );
> -        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ),
> $loanlength, $branch, $borrower );
> +        unless ($loanlength or
> C4::Context->preference("AllowNotForLoanOverride")) {
> +             $issuingimpossible{LOAN_LENGTH_UNDEFINED} =
> "$borrower->{'categorycode'}, $itype, $branch";
> +        }
> +        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ),
> $loanlength, $branch, $borrower ) ;
>
>         # Offline circ calls AddIssue directly, doesn't run through here
>         #  So issuingimpossible should be ok.
> @@ -711,15 +707,22 @@ sub CanBookBeIssued {
>         $issuingimpossible{CARD_LOST} = 1;
>     }
>     if ( $borrower->{flags}->{'DBARRED'} ) {
> -        $issuingimpossible{DEBARRED} = 1;
> +               if (my
> $dateenddebarred=$borrower->{flags}->{'DBARRED'}->{'dateend'}){
> +               $issuingimpossible{DEBARRED} =
> format_date($dateenddebarred);
> +               }
> +               else {
> +               $issuingimpossible{DEBARRED} = 1;
> +               }
>     }
>     if ( $borrower->{'dateexpiry'} eq '0000-00-00') {
>         $issuingimpossible{EXPIRED} = 1;
>     } else {
> -        my @expirydate=  split /-/,$borrower->{'dateexpiry'};
> -        if($expirydate[0]==0 || $expirydate[1]==0|| $expirydate[2]==0 ||
> -            Date_to_Days(Today) > Date_to_Days( @expirydate )) {
> -            $issuingimpossible{EXPIRED} = 1;
> +        my @expirydate = split (/-/, $borrower->{'dateexpiry'});
> +        if (   $expirydate[0] == 0
> +            || $expirydate[1] == 0
> +            || $expirydate[2] == 0
> +            || Date_to_Days(Today) > Date_to_Days(@expirydate) ) {
> +            $issuingimpossible{EXPIRED} = 1;
>         }
>     }
>     #
> @@ -761,14 +764,15 @@ sub CanBookBeIssued {
>  #
>     # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
>     #
> -       my $toomany = TooMany( $borrower, $item->{biblionumber}, $item );
> -    # if TooMany return / 0, then the user has no permission to check out
> this book
> -    if ($toomany =~ /\/ 0/) {
> +    my @toomany = TooMany( $borrower, $item->{biblionumber}, $item );
> +
> +    if ( $toomany[0] == 1 && scalar(@toomany)<3) {
>         $needsconfirmation{PATRON_CANT} = 1;
> -    } else {
> -        $needsconfirmation{TOO_MANY} = $toomany if $toomany;
> +    } elsif (scalar(@toomany)==3) {
> +        $needsconfirmation{TOO_MANY} = "$toomany[1] / $toomany[2]";
>     }
>
> +
>     #
>     # ITEM CHECKING
>     #
> @@ -805,8 +809,18 @@ sub CanBookBeIssued {
>             }
>         }
>     }
> -    if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 )
> -    {
> +    if ( $item->{'damaged'} && $item->{'damaged'} > 0 ){
> +        $needsconfirmation{DAMAGED} = $item->{'damaged'};
> +        my $fw                      =
> GetFrameworkCode($item->{biblionumber});
> +        my $category                = GetAuthValCode('items.damaged',$fw);
> +        my $authorizedvalues        = GetAuthorisedValues($category,
> $item->{damaged});
> +
> +        foreach my $authvalue (@$authorizedvalues){
> +            $needsconfirmation{DAMAGED} = $authvalue->{lib} if
> $authvalue->{'authorised_value'} eq $item->{'damaged'};
> +        }
> +
> +    }
> +    if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) {
>         $issuingimpossible{WTHDRAWN} = 1;
>     }
>     if (   $item->{'restricted'}
> @@ -814,15 +828,23 @@ sub CanBookBeIssued {
>     {
>         $issuingimpossible{RESTRICTED} = 1;
>     }
> +    my $userenv = C4::Context->userenv;
> +    my $branch=$userenv->{branch};
> +    my $hbr= $item->{ C4::Context->preference("HomeOrHoldingBranch") };
>     if ( C4::Context->preference("IndependantBranches") ) {
> -        my $userenv = C4::Context->userenv;
>         if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) {
>             $issuingimpossible{ITEMNOTSAMEBRANCH} = 1
> -              if ( $item->{C4::Context->preference("HomeOrHoldingBranch")}
> ne $userenv->{branch} );
> +              if ( $hbr ne $branch );
>             $needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName(
> $borrower->{'branchcode'} )
>               if ( $borrower->{'branchcode'} ne $userenv->{branch} );
>         }
>     }
> +    my
> $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq
> "ccode" ? "ccode" : "itype";
> +    if  ( C4::Context->preference("UseBranchTransferLimits")
> +                and !IsBranchTransferAllowed( $branch, $hbr, $item->{
> $branchtransferfield } ) ) {
> +        $needsconfirmation{BRANCH_TRANSFER_NOT_ALLOWED} = $hbr;
> +    }
> +
>
>     #
>     # CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER
> @@ -860,20 +882,21 @@ sub CanBookBeIssued {
>                my ( $resborrower ) = C4::Members::GetMemberDetails(
> $resbor, 0 );
>                my $branches  = GetBranches();
>                my $branchname = $branches->{ $res->{'branchcode'}
> }->{'branchname'};
> -        if ( $resbor ne $borrower->{'borrowernumber'} && $restype eq
> "Waiting" )
> -        {
> -            # The item is on reserve and waiting, but has been
> -            # reserved by some other patron.
> -            $needsconfirmation{RESERVE_WAITING} =
> -"$resborrower->{'firstname'} $resborrower->{'surname'}
> ($resborrower->{'cardnumber'}, $branchname)";
> -        }
> -        elsif ( $restype eq "Reserved" ) {
> -            # The item is on reserve for someone else.
> -            $needsconfirmation{RESERVED} =
> -"$res->{'reservedate'} : $resborrower->{'firstname'}
> $resborrower->{'surname'} ($resborrower->{'cardnumber'})";
> +        if( $resbor ne $borrower->{'borrowernumber'}){
> +            if ( $restype eq "Waiting" ) {
> +                # The item is on reserve and waiting, but has been
> +                # reserved by some other patron.
> +                $needsconfirmation{RESERVE_WAITING} =
> +    "$resborrower->{'firstname'} $resborrower->{'surname'}
> ($resborrower->{'cardnumber'}, $branchname)";
> +            }
> +            elsif ( $restype eq "Reserved" ) {
> +                # The item is on reserve for someone else.
> +                $needsconfirmation{RESERVED} =
> +    "$res->{'reservedate'} : $resborrower->{'firstname'}
> $resborrower->{'surname'} ($resborrower->{'cardnumber'})";
> +            }
>         }
>     }
> -       return ( \%issuingimpossible, \%needsconfirmation );
> +    return ( \%issuingimpossible, \%needsconfirmation );
>  }
>
>  =head2 AddIssue
> @@ -954,7 +977,10 @@ sub AddIssue {
>                                # who wants to borrow it now. mark it
> returned before issuing to the new borrower
>                                AddReturn(
>                                        $item->{'barcode'},
> -                                       C4::Context->userenv->{'branch'}
> +                                       C4::Context->userenv->{'branch'},
> +                                       undef,
> +                                       undef,
> +                                       1
>                                );
>                        }
>
> @@ -987,7 +1013,9 @@ sub AddIssue {
>                                        ModReserve(1,
>                                                $res->{'biblionumber'},
>                                                $res->{'borrowernumber'},
> -                                               $res->{'branchcode'}
> +                                               $res->{'branchcode'},
> +                                               undef,
> +                                               $res->{'reservenumber'}
>                                        );
>                                }
>                        }
> @@ -1077,10 +1105,11 @@ sub AddIssue {
>                 branch   => $branch,
>             });
>         }
> +
> +        logaction( "CIRCULATION", "ISSUE", $borrower->{'borrowernumber'},
> $item->{'itemnumber'}  )
> +          if C4::Context->preference("IssueLog");
>     }
>
> -    logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'},
> $biblio->{'biblionumber'})
> -        if C4::Context->preference("IssueLog");
>   }
>   return ($datedue);   # not necessarily the same as when it came in!
>  }
> @@ -1095,254 +1124,8 @@ Get loan length for an itemtype, a borrower type
> and a branch
>
>  sub GetLoanLength {
>     my ( $borrowertype, $itemtype, $branchcode ) = @_;
> -    my $dbh = C4::Context->dbh;
> -    my $sth =
> -      $dbh->prepare(
> -"select issuelength from issuingrules where categorycode=? and itemtype=?
> and branchcode=? and issuelength is not null"
> -      );
> -# warn "in get loan lenght $borrowertype $itemtype $branchcode ";
> -# try to find issuelength & return the 1st available.
> -# check with borrowertype, itemtype and branchcode, then without one of
> those parameters
> -    $sth->execute( $borrowertype, $itemtype, $branchcode );
> -    my $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( $borrowertype, "*", $branchcode );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( "*", $itemtype, $branchcode );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( "*", "*", $branchcode );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( $borrowertype, $itemtype, "*" );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( $borrowertype, "*", "*" );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( "*", $itemtype, "*" );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    $sth->execute( "*", "*", "*" );
> -    $loanlength = $sth->fetchrow_hashref;
> -    return $loanlength->{issuelength}
> -      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
> -
> -    # if no rule is set => 21 days (hardcoded)
> -    return 21;
> -}
> -
> -=head2 GetIssuingRule
> -
> -  my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode)
> -
> -FIXME - This is a copy-paste of GetLoanLength
> -as a stop-gap.  Do not wish to change API for GetLoanLength
> -this close to release, however, Overdues::GetIssuingRules is broken.
> -
> -Get the issuing rule for an itemtype, a borrower type and a branch
> -Returns a hashref from the issuingrules table.
> -
> -=cut
> -
> -sub GetIssuingRule {
> -    my ( $borrowertype, $itemtype, $branchcode ) = @_;
> -    my $dbh = C4::Context->dbh;
> -    my $sth =  $dbh->prepare( "select * from issuingrules where
> categorycode=? and itemtype=? and branchcode=? and issuelength is not null"
>  );
> -    my $irule;
> -
> -       $sth->execute( $borrowertype, $itemtype, $branchcode );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( $borrowertype, "*", $branchcode );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( "*", $itemtype, $branchcode );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( "*", "*", $branchcode );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( $borrowertype, $itemtype, "*" );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( $borrowertype, "*", "*" );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( "*", $itemtype, "*" );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    $sth->execute( "*", "*", "*" );
> -    $irule = $sth->fetchrow_hashref;
> -    return $irule if defined($irule) ;
> -
> -    # if no rule matches,
> -    return undef;
> -}
> -
> -=head2 GetBranchBorrowerCircRule
> -
> -  my $branch_cat_rule = GetBranchBorrowerCircRule($branchcode,
> $categorycode);
> -
> -Retrieves circulation rule attributes that apply to the given
> -branch and patron category, regardless of item type.
> -The return value is a hashref containing the following key:
> -
> -maxissueqty - maximum number of loans that a
> -patron of the given category can have at the given
> -branch.  If the value is undef, no limit.
> -
> -This will first check for a specific branch and
> -category match from branch_borrower_circ_rules.
> -
> -If no rule is found, it will then check default_branch_circ_rules
> -(same branch, default category).  If no rule is found,
> -it will then check default_borrower_circ_rules (default
> -branch, same category), then failing that, default_circ_rules
> -(default branch, default category).
> -
> -If no rule has been found in the database, it will default to
> -the buillt in rule:
> -
> -maxissueqty - undef
> -
> -C<$branchcode> and C<$categorycode> should contain the
> -literal branch code and patron category code, respectively - no
> -wildcards.
> -
> -=cut
> -
> -sub GetBranchBorrowerCircRule {
> -    my $branchcode = shift;
> -    my $categorycode = shift;
> -
> -    my $branch_cat_query = "SELECT maxissueqty
> -                            FROM branch_borrower_circ_rules
> -                            WHERE branchcode = ?
> -                            AND   categorycode = ?";
> -    my $dbh = C4::Context->dbh();
> -    my $sth = $dbh->prepare($branch_cat_query);
> -    $sth->execute($branchcode, $categorycode);
> -    my $result;
> -    if ($result = $sth->fetchrow_hashref()) {
> -        return $result;
> -    }
> -
> -    # try same branch, default borrower category
> -    my $branch_query = "SELECT maxissueqty
> -                        FROM default_branch_circ_rules
> -                        WHERE branchcode = ?";
> -    $sth = $dbh->prepare($branch_query);
> -    $sth->execute($branchcode);
> -    if ($result = $sth->fetchrow_hashref()) {
> -        return $result;
> -    }
> -
> -    # try default branch, same borrower category
> -    my $category_query = "SELECT maxissueqty
> -                          FROM default_borrower_circ_rules
> -                          WHERE categorycode = ?";
> -    $sth = $dbh->prepare($category_query);
> -    $sth->execute($categorycode);
> -    if ($result = $sth->fetchrow_hashref()) {
> -        return $result;
> -    }
> -
> -    # try default branch, default borrower category
> -    my $default_query = "SELECT maxissueqty
> -                          FROM default_circ_rules";
> -    $sth = $dbh->prepare($default_query);
> -    $sth->execute();
> -    if ($result = $sth->fetchrow_hashref()) {
> -        return $result;
> -    }
> -
> -    # built-in default circulation rule
> -    return {
> -        maxissueqty => undef,
> -    };
> -}
> -
> -=head2 GetBranchItemRule
> -
> -  my $branch_item_rule = GetBranchItemRule($branchcode, $itemtype);
> -
> -Retrieves circulation rule attributes that apply to the given
> -branch and item type, regardless of patron category.
> -
> -The return value is a hashref containing the following key:
> -
> -holdallowed => Hold policy for this branch and itemtype. Possible values:
> -  0: No holds allowed.
> -  1: Holds allowed only by patrons that have the same homebranch as the
> item.
> -  2: Holds allowed from any patron.
> -
> -This searches branchitemrules in the following order:
> -
> -  * Same branchcode and itemtype
> -  * Same branchcode, itemtype '*'
> -  * branchcode '*', same itemtype
> -  * branchcode and itemtype '*'
> -
> -Neither C<$branchcode> nor C<$categorycode> should be '*'.
> -
> -=cut
> -
> -sub GetBranchItemRule {
> -    my ( $branchcode, $itemtype ) = @_;
> -    my $dbh = C4::Context->dbh();
> -    my $result = {};
> -
> -    my @attempts = (
> -        ['SELECT holdallowed
> -            FROM branch_item_rules
> -            WHERE branchcode = ?
> -              AND itemtype = ?', $branchcode, $itemtype],
> -        ['SELECT holdallowed
> -            FROM default_branch_circ_rules
> -            WHERE branchcode = ?', $branchcode],
> -        ['SELECT holdallowed
> -            FROM default_branch_item_rules
> -            WHERE itemtype = ?', $itemtype],
> -        ['SELECT holdallowed
> -            FROM default_circ_rules'],
> -    );
> -
> -    foreach my $attempt (@attempts) {
> -        my ($query, @bind_params) = @{$attempt};
> -
> -        # Since branch/category and branch/itemtype use the same
> per-branch
> -        # defaults tables, we have to check that the key we want is set,
> not
> -        # just that a row was returned
> -        return $result if ( defined( $result->{'holdallowed'} =
> $dbh->selectrow_array( $query, {}, @bind_params ) ) );
> -    }
> -
> -    # built-in default circulation rule
> -    return {
> -        holdallowed => 2,
> -    };
> +    my $loanlength=GetIssuingRule($borrowertype,$itemtype,$branchcode);
> +    return $loanlength->{issuelength};
>  }
>
>  =head2 AddReturn
> @@ -1420,8 +1203,8 @@ patron who last borrowed the book.
>  =cut
>
>  sub AddReturn {
> -    my ( $barcode, $branch, $exemptfine, $dropbox ) = @_;
> -    if ($branch and not GetBranchDetail($branch)) {
> +    my ( $barcode, $branch, $exemptfine, $dropbox, $force) = @_;
> +    if ( $branch and not GetBranchDetail($branch) ) {
>         warn "AddReturn error: branch '$branch' not found.  Reverting to "
> . C4::Context->userenv->{'branch'};
>         undef $branch;
>     }
> @@ -1465,9 +1248,17 @@ sub AddReturn {
>         my $branches = GetBranches();    # a potentially expensive call for
> a non-feature.
>         $branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr;
>     }
> -
> +    my
> $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq
> "ccode" ? "ccode" : "itype";
> +    $debug && warn "$branch, $hbr,
> ",C4::Context->preference("BranchTransferLimitsType")," ,",$item->{
> $branchtransferfield } ;
> +    $debug && warn Dump($item);
> +    $debug && warn IsBranchTransferAllowed( $branch, $hbr, $item->{
> C4::Context->preference("BranchTransferLimitsType") } );
>     # if indy branches and returning to different branch, refuse the return
> -    if ($hbr ne $branch &&
> C4::Context->preference("IndependantBranches")){
> +    if ( !$force && ($hbr ne $branch)
> +               && (C4::Context->preference("IndependantBranches")
> +                       or (
> C4::Context->preference("UseBranchTransferLimits")
> +                and !IsBranchTransferAllowed( $branch, $hbr,
> $item->{$branchtransferfield } ) )
> +                   )
> +               ){
>         $messages->{'Wrongbranch'} = {
>             Wrongbranch => $branch,
>             Rightbranch => $hbr,
> @@ -1478,7 +1269,6 @@ sub AddReturn {
>         # FIXME - even in an indy branches situation, there should
>         # still be an option for the library to accept the item
>         # and transfer it to its owning library.
> -        return ( $doreturn, $messages, $issue, $borrower );
>     }
>
>     if ( $item->{'wthdrawn'} ) { # book has been cancelled
> @@ -1489,12 +1279,11 @@ sub AddReturn {
>     # case of a return of document (deal with issues and holdingbranch)
>     if ($doreturn) {
>         $borrower or warn "AddReturn without current borrower";
> -               my $circControlBranch;
> +        my $circControlBranch;
>         if ($dropbox) {
> -            # define circControlBranch only if dropbox mode is set
> -            # don't allow dropbox mode to create an invalid entry in
> issues (issuedate > today)
> -            # FIXME: check issuedate > returndate, factoring in holidays
> -            $circControlBranch = _GetCircControlBranch($item,$borrower)
> unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );;
> +            $circControlBranch = _GetCircControlBranch( $item, $borrower
> );
> +            # don't allow dropbox mode to create an invalid entry in
> issues (issuedate > returndate) FIXME: actually checks eq, not gt
> +            undef($dropbox) if ( $item->{'issuedate'} eq
> C4::Dates->today('iso') );
>         }
>
>         if ($borrowernumber) {
> @@ -1502,15 +1291,15 @@ sub AddReturn {
>             $messages->{'WasReturned'} = 1;    # FIXME is the "= 1" right?
>  This could be the borrower hash.
>         }
>
> -        ModItem({ onloan => undef }, $issue->{'biblionumber'},
> $item->{'itemnumber'});
> +        ModItem( { renewals=>0, onloan => undef },
> $issue->{'biblionumber'}, $item->{'itemnumber'} );
> +       # the holdingbranch is updated if the document is returned to
> another location.
> +       # this is always done regardless of whether the item was on loan or
> not
> +       if ( $item->{'holdingbranch'} ne $branch ) {
> +                   UpdateHoldingbranch( $branch, $item->{'itemnumber'} );
> +            $item->{'holdingbranch'} = $branch;    # update item data
> holdingbranch too
> +           }
>     }
>
> -    # the holdingbranch is updated if the document is returned to another
> location.
> -    # this is always done regardless of whether the item was on loan or
> not
> -    if ($item->{'holdingbranch'} ne $branch) {
> -        UpdateHoldingbranch($branch, $item->{'itemnumber'});
> -        $item->{'holdingbranch'} = $branch; # update item data
> holdingbranch too
> -    }
>     ModDateLastSeen( $item->{'itemnumber'} );
>
>     # check if we have a transfer for this document
> @@ -1537,11 +1326,26 @@ sub AddReturn {
>         _FixAccountForLostAndReturned($item->{'itemnumber'},
> $borrowernumber, $barcode);    # can tolerate undef $borrowernumber
>         $messages->{'WasLost'} = 1;
>     }
> +    if ($item->{'notforloan'}){
> +        $messages->{'NotForLoan'} = $item->{'notforloan'};
> +    }
> +    if ($item->{'damaged'}){
> +        $messages->{'Damaged'} = $item->{'damaged'};
> +    }
>
> -    # fix up the overdues in accounts...
> -    if ($borrowernumber) {
> +    if ($borrowernumber && $doreturn) {
> +        # fix up the overdues in accounts...
>         my $fix = _FixOverduesOnReturn($borrowernumber,
> $item->{itemnumber}, $exemptfine, $dropbox);
>         defined($fix) or warn "_FixOverduesOnReturn($borrowernumber,
> $item->{itemnumber}...) failed!";  # zero is OK, check defined
> +
> +        # fix fine days
> +        my $debardate = _FixFineDaysOnReturn($borrower, $item,
> $issue->{date_due});
> +        $messages->{'Debarred'} = $debardate if($debardate);
> +
> +        # get fines for the borrower
> +        my $fineamount = C4::Overdues::GetFine($borrowernumber);
> +        $messages->{'HaveFines'} = $fineamount if($fineamount);
> +
>     }
>
>     # find reserves.....
> @@ -1577,20 +1381,20 @@ sub AddReturn {
>             branch   => $branch,
>         });
>     }
> -
> -    logaction("CIRCULATION", "RETURN", $borrowernumber,
> $item->{'biblionumber'})
> -        if C4::Context->preference("ReturnLog");
> -
> +
> +    logaction( "CIRCULATION", "RETURN", $borrowernumber,
> $item->{'itemnumber'} )
> +      if C4::Context->preference("ReturnLog");
> +
>     # FIXME: make this comment intelligible.
>     #adding message if holdingbranch is non equal a userenv branch to
> return the document to homebranch
>     #we check, if we don't have reserv or transfert for this document, if
> not, return it to homebranch .
>
> -    if ($doreturn and ($branch ne $hbr) and not
> $messages->{'WrongTransfer'} and ($validTransfert ne 1) ){
> -        if ( C4::Context->preference("AutomaticItemReturn"    ) or
> -            (C4::Context->preference("UseBranchTransferLimits") and
> -             ! IsBranchTransferAllowed($branch, $hbr,
> $item->{C4::Context->preference("BranchTransferLimitsType")} )
> -           )) {
> -            $debug and warn sprintf "about to call ModItemTransfer(%s, %s,
> %s)", $item->{'itemnumber'},$branch, $hbr;
> +    if ( $doreturn and ( $branch ne $hbr ) and not
> $messages->{'WrongTransfer'} and ( $validTransfert ne 1 ) ) {
> +        if (C4::Context->preference("AutomaticItemReturn")
> +            or ( C4::Context->preference("UseBranchTransferLimits")
> +                and !IsBranchTransferAllowed( $branch, $hbr, $item->{
> $branchtransferfield } ) )
> +          ) {
> +            $debug and warn sprintf "about to call ModItemTransfer(%s, %s,
> %s)", $item->{'itemnumber'}, $branch, $hbr;
>             $debug and warn "item: " . Dumper($item);
>             ModItemTransfer($item->{'itemnumber'}, $branch, $hbr);
>             $messages->{'WasTransfered'} = 1;
> @@ -1652,6 +1456,61 @@ sub MarkIssueReturned {
>     $sth_del->execute($borrowernumber, $itemnumber);
>  }
>
> +=head2 _FixFineDaysOnReturn
> +
> +    &_FixFineDaysOnReturn($borrower, $item, $datedue);
> +
> +C<$borrower> borrower hashref
> +
> +C<$item> item hashref
> +
> +C<$datedue> date due
> +
> +Internal function, called only by AddReturn that calculate and update the
> user fine days, and debars him
> +
> +=cut
> +
> +sub _FixFineDaysOnReturn {
> +    my ($borrower, $item, $datedue) = @_;
> +
> +    if($datedue){
> +        $datedue = C4::Dates->new($datedue,"iso");
> +    }else{
> +        return;
> +    }
> +
> +    my $branchcode  =_GetCircControlBranch($item, $borrower);
> +    my $calendar    = C4::Calendar->new( branchcode => $branchcode );
> +    my $today       = C4::Dates->new();
> +
> +    my $deltadays = $calendar->daysBetween($datedue, C4::Dates->new());
> +
> +    my $circcontrol = C4::Context::preference('CircControl');
> +    my $issuingrule = GetIssuingRule($borrower->{categorycode},
> $item->{itype}, $branchcode);
> +    my $finedays    = $issuingrule->{finedays};
> +    # exit if no finedays defined
> +    return unless $finedays;
> +    my $grace       = $issuingrule->{firstremind};
> +
> +    if( $deltadays - $grace > 0){
> +        my @newdate     = Add_Delta_Days(Today(), $deltadays * $finedays
> );
> +        my $isonewdate  = join('-', at newdate);
> +        my ($deby, $debm, $debd) = split(/-/,$borrower->{debarred});
> +        if(check_date($deby, $debm, $debd)){
> +            my @olddate = split(/-/, $borrower->{debarred});
> +
> +            if(Delta_Days(@olddate, at newdate) > 0){
> +                C4::Members::DebarMember($borrower->{borrowernumber},
> $isonewdate);
> +                return $isonewdate;
> +            }
> +        }else{
> +            C4::Members::DebarMember($borrower->{borrowernumber},
> $isonewdate);
> +            return $isonewdate;
> +        }
> +    }
> +}
> +
> +
>  =head2 _FixOverduesOnReturn
>
>    &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode);
> @@ -1826,7 +1685,7 @@ sub _GetCircControlBranch {
>     my $circcontrol = C4::Context->preference('CircControl');
>     my $branch;
>
> -    if ($circcontrol eq 'PickupLibrary') {
> +    if ($circcontrol eq 'PickupLibrary' &&
> C4::Context->userenv->{'branch'}) {
>         $branch= C4::Context->userenv->{'branch'};
>     } elsif ($circcontrol eq 'PatronLibrary') {
>         $branch=$borrower->{branchcode};
> @@ -1863,7 +1722,7 @@ sub GetItemIssue {
>     my ($itemnumber) = @_;
>     return unless $itemnumber;
>     my $sth = C4::Context->dbh->prepare(
> -        "SELECT *
> +        "SELECT *, issues.renewals as 'issues.renewals'
>         FROM issues
>         LEFT JOIN items ON issues.itemnumber=items.itemnumber
>         WHERE issues.itemnumber=?");
> @@ -1934,7 +1793,7 @@ sub GetItemIssues {
>     }
>     my $results = $sth->fetchall_arrayref({});
>     foreach (@$results) {
> -        $_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0;
> +        $_->{'overdue'} = ( $_->{'date_due'} lt $today &&
> !defined($_->{return_date}) ) ? 1 : 0;
>     }
>     return $results;
>  }
> @@ -2040,69 +1899,42 @@ already renewed the loan. $error will contain the
> reason the renewal can not pro
>  sub CanBookBeRenewed {
>
>     # check renewal status
> -    my ( $borrowernumber, $itemnumber, $override_limit ) = @_;
> +    my ( $borrowernumber, $itemnumber ) = @_;
>     my $dbh       = C4::Context->dbh;
>     my $renews    = 1;
> -    my $renewokay = 0;
> -       my $error;
> +    my $renewokay = 1;
> +    my $error;
>
>     # Look in the issues table for this item, lent to this borrower,
>     # and not yet returned.
>
>     # Look in the issues table for this item, lent to this borrower,
>     # and not yet returned.
> -    my %branch = (
> -            'ItemHomeLibrary' => 'items.homebranch',
> -            'PickupLibrary'   => 'items.holdingbranch',
> -            'PatronLibrary'   => 'borrowers.branchcode'
> -            );
> -    my $controlbranch = $branch{C4::Context->preference('CircControl')};
> -    my $itype         = C4::Context->preference('item-level_itypes') ?
> 'items.itype' : 'biblioitems.itemtype';
> +    my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or
> return undef;
> +    my $item = GetItem($itemnumber) or return undef;
> +    my $itemissue = GetItemIssue($itemnumber) or return undef;
> +    my $branchcode = _GetCircControlBranch($item, $borrower);
> +    if ($itemissue->{'overdue'}){
> +       $renewokay=0;
> +       $error->{message}='overdue';
> +    }
>
> -    my $sthcount = $dbh->prepare("
> -                   SELECT
> -                    borrowers.categorycode, biblioitems.itemtype,
> issues.renewals, renewalsallowed, $controlbranch
> -                   FROM  issuingrules,
> -                   issues
> -                   LEFT JOIN items USING (itemnumber)
> -                   LEFT JOIN borrowers USING (borrowernumber)
> -                   LEFT JOIN biblioitems USING (biblioitemnumber)
> -
> -                   WHERE
> -                    (issuingrules.categorycode = borrowers.categorycode OR
> issuingrules.categorycode = '*')
> -                   AND
> -                    (issuingrules.itemtype = $itype OR
> issuingrules.itemtype = '*')
> -                   AND
> -                    (issuingrules.branchcode = $controlbranch OR
> issuingrules.branchcode = '*')
> -                   AND
> -                    borrowernumber = ?
> -                   AND
> -                    itemnumber = ?
> -                   ORDER BY
> -                    issuingrules.categorycode desc,
> -                    issuingrules.itemtype desc,
> -                    issuingrules.branchcode desc
> -                   LIMIT 1;
> -                  ");
> -
> -    $sthcount->execute( $borrowernumber, $itemnumber );
> -    if ( my $data1 = $sthcount->fetchrow_hashref ) {
> -
> -        if ( ( $data1->{renewalsallowed} && $data1->{renewalsallowed} >
> $data1->{renewals} ) || $override_limit ) {
> -            $renewokay = 1;
> -        }
> -        else {
> -                       $error="too_many";
> -               }
> -
> -        my ( $resfound, $resrec ) =
> C4::Reserves::CheckReserves($itemnumber);
> -        if ($resfound) {
> -            $renewokay = 0;
> -                       $error="on_reserve"
> -        }
> +    my $issuingrule = GetIssuingRule($borrower->{categorycode},
> $item->{itype}, $branchcode);
> +
> +    if ( $issuingrule->{renewalsallowed} <=
> $itemissue->{'issues.renewals'} )  {
> +        $renewokay=0;
> +        $error->{message} = "too_many";
> +    }
>
> +    my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber);
> +    if ($resfound) {
> +        $renewokay = 0;
> +        $error->{message} = "on_reserve";
>     }
> -    return ($renewokay,$error);
> +    $error->{renewals}       = $itemissue->{'issues.renewals'};
> +    $error->{renewalsallowed}= $issuingrule->{renewalsallowed};
> +
> +    return ( $renewokay, $error );
>  }
>
>  =head2 AddRenewal
> @@ -2157,22 +1989,28 @@ sub AddRenewal {
>     # based on the value of the RenewalPeriodBase syspref.
>     unless ($datedue) {
>
> -        my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 )
> or return undef;
> -        my $loanlength = GetLoanLength(
> -                    $borrower->{'categorycode'},
> -                    (C4::Context->preference('item-level_itypes')) ?
> $biblio->{'itype'} : $biblio->{'itemtype'} ,
> -                               $issuedata->{'branchcode'}  );   # that's
> the circ control branch.
> +        my $borrower   = C4::Members::GetMemberDetails( $borrowernumber, 0
> ) or return undef;
> +        my $branchcode = _GetCircControlBranch($item, $borrower);
> +        my $loanlength = GetIssuingRule( $borrower->{categorycode},
> $item->{itype}, $branchcode );
> +
> +        $datedue =
> +          ( C4::Context->preference('RenewalPeriodBase') eq 'date_due' )
> +          ? C4::Dates->new( $issuedata->{date_due}, 'iso' )
> +          : C4::Dates->new();
> +
> +        my $itype = ( C4::Context->preference('item-level_itypes') ) ?
> $biblio->{'itype'} : $biblio->{'itemtype'};
> +        my $controlbranch = _GetCircControlBranch( $item, $borrower );
> +        my $renewalperiod = $loanlength->{renewalperiod} || GetLoanLength(
> $borrower->{'categorycode'}, $itype, $controlbranch );
> +
> +        $datedue = CalcDateDue( $datedue, $renewalperiod,
> $issuedata->{'branchcode'}, $borrower );
>
> -        $datedue = (C4::Context->preference('RenewalPeriodBase') eq
> 'date_due') ?
> -
>  C4::Dates->new($issuedata->{date_due}, 'iso') :
> -                                        C4::Dates->new();
> -        $datedue =
>  CalcDateDue($datedue,$loanlength,$issuedata->{'branchcode'},$borrower);
>     }
>
>     # Update the issues record to have the new due date, and a new count
>     # of how many times it has been renewed.
>     my $renews = $issuedata->{'renewals'} + 1;
> -    $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?,
> lastreneweddate = ?
> +    $sth = $dbh->prepare(
> +        "UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
>                             WHERE borrowernumber=?
>                             AND itemnumber=?"
>     );
> @@ -2180,8 +2018,8 @@ sub AddRenewal {
>     $sth->finish;
>
>     # Update the renewal count on the item, and tell zebra to reindex
> -    $renews = $biblio->{'renewals'} + 1;
> -    ModItem({ renewals => $renews, onloan => $datedue->output('iso') },
> $biblio->{'biblionumber'}, $itemnumber);
> +    $renews = $item->{'renewals'} + 1;
> +    ModItem( { renewals => $renews, onloan => $datedue->output('iso') },
> undef, $itemnumber );
>
>     # Charge a new rental fee, if applicable?
>     my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber
> );
> @@ -2547,15 +2385,8 @@ sub CalcDateDue {
>        my ($startdate,$loanlength,$branch,$borrower) = @_;
>        my $datedue;
>
> -       if(C4::Context->preference('useDaysMode') eq 'Days') {  # ignoring
> calendar
> -               my $timedue = time + ($loanlength) * 86400;
> -       #FIXME - assumes now even though we take a startdate
> -               my @datearr  = localtime($timedue);
> -               $datedue = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 +
> $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso');
> -       } else {
> -               my $calendar = C4::Calendar->new(  branchcode => $branch );
> -               $datedue = $calendar->addDate($startdate, $loanlength);
> -       }
> +       my $calendar = C4::Calendar->new(  branchcode => $branch );
> +       $datedue = $calendar->addDate($startdate, $loanlength);
>
>        # if ReturnBeforeExpiry ON the datedue can't be after borrower
> expirydate
>        if ( C4::Context->preference('ReturnBeforeExpiry') &&
> $datedue->output('iso') gt $borrower->{dateexpiry} ) {
> @@ -2765,18 +2596,121 @@ sub CreateBranchTransferLimit {
>
>  =head2 DeleteBranchTransferLimits
>
> -  DeleteBranchTransferLimits();
> +  DeleteBranchTransferLimits($tobranch);
>
>  =cut
>
>  sub DeleteBranchTransferLimits {
> -   my $dbh = C4::Context->dbh;
> -   my $sth = $dbh->prepare("TRUNCATE TABLE branch_transfer_limits");
> -   $sth->execute();
> +    my $branch = shift;
> +    my $dbh = C4::Context->dbh;
> +    my $sth = $dbh->prepare("DELETE FROM branch_transfer_limits WHERE
> toBranch = ?");
> +    $sth->execute($branch);
> +}
> +
> +sub GetOfflineOperations {
> +       my $dbh = C4::Context->dbh;
> +       my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations
> WHERE branchcode=? ORDER BY timestamp");
> +       $sth->execute(C4::Context->userenv->{'branch'});
> +       my $results = $sth->fetchall_arrayref({});
> +       $sth->finish;
> +       return $results;
> +}
> +
> +sub GetOfflineOperation {
> +       my $dbh = C4::Context->dbh;
> +       my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations
> WHERE operationid=?");
> +       $sth->execute( shift );
> +       my $result = $sth->fetchrow_hashref;
> +       $sth->finish;
> +       return $result;
> +}
> +
> +sub AddOfflineOperation {
> +       my $dbh = C4::Context->dbh;
> +       warn Data::Dumper::Dumper(@_);
> +       my $sth = $dbh->prepare("INSERT INTO pending_offline_operations
> VALUES('',?,?,?,?,?,?)");
> +       $sth->execute( @_ );
> +       return "Added.";
> +}
> +
> +sub DeleteOfflineOperation {
> +       my $dbh = C4::Context->dbh;
> +       my $sth = $dbh->prepare("DELETE FROM pending_offline_operations
> WHERE operationid=?");
> +       $sth->execute( shift );
> +       return "Deleted.";
> +}
> +
> +sub ProcessOfflineOperation {
> +       my $operation = shift;
> +
> +    my $report;
> +       if ( $operation->{action} eq 'return' ) {
> +        $report = ProcessOfflineReturn( $operation );
> +       } elsif ( $operation->{action} eq 'issue' ) {
> +           $report = ProcessOfflineIssue( $operation );
> +       }
> +
> +       DeleteOfflineOperation( $operation->{operationid} ) if
> $operation->{operationid};
> +
> +       return $report;
> +}
> +
> +sub ProcessOfflineReturn {
> +    my $operation = shift;
> +
> +    my $itemnumber = C4::Items::GetItemnumberFromBarcode(
> $operation->{barcode} );
> +
> +    if ( $itemnumber ) {
> +        my $issue = GetOpenIssue( $itemnumber );
> +        if ( $issue ) {
> +            MarkIssueReturned(
> +                $issue->{borrowernumber},
> +                $itemnumber,
> +                undef,
> +                $operation->{timestamp},
> +            );
> +            return "Success.";
> +        } else {
> +            return "Item not issued.";
> +        }
> +    } else {
> +        return "Item not found.";
> +    }
> +}
> +
> +sub ProcessOfflineIssue {
> +    my $operation = shift;
> +
> +    my $borrower = C4::Members::GetMemberDetails( undef,
> $operation->{cardnumber} ); # Get borrower from operation cardnumber
> +
> +    if ( $borrower->{borrowernumber} ) {
> +        my $itemnumber = C4::Items::GetItemnumberFromBarcode(
> $operation->{barcode} );
> +        my $issue = GetOpenIssue( $itemnumber );
> +
> +        if ( $issue and ( $issue->{borrowernumber} ne
> $borrower->{borrowernumber} ) ) { # Item already issued to another borrower,
> mark it returned
> +            MarkIssueReturned(
> +                $issue->{borrowernumber},
> +                $itemnumber,
> +                undef,
> +                $operation->{timestamp},
> +            );
> +        }
> +        AddIssue(
> +            $borrower,
> +            $operation->{'barcode'},
> +            undef,
> +            1,
> +            $operation->{timestamp},
> +            undef,
> +        );
> +        return "Success.";
> +    } else {
> +        return "Borrower not found.";
> +    }
>  }
>
>
> -  1;
> +1;
>
>  __END__
>
> diff --git a/C4/IssuingRules.pm b/C4/IssuingRules.pm
> new file mode 100644
> index 0000000..b64b817
> --- /dev/null
> +++ b/C4/IssuingRules.pm
> @@ -0,0 +1,261 @@
> +package C4::IssuingRules;
> +
> +# Copyright 2009 BibLibre SARL
> +#
> +# This file is part of Koha.
> +#
> +# Koha is free software; you can redistribute it and/or modify it under
> the
> +# terms of the GNU General Public License as published by the Free
> Software
> +# Foundation; either version 2 of the License, or (at your option) any
> later
> +# version.
> +#
> +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> FITNESS FOR
> +# A PARTICULAR PURPOSE.  See the GNU General Public License for more
> details.
> +#
> +# You should have received a copy of the GNU General Public License along
> with
> +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple
> Place,
> +# Suite 330, Boston, MA  02111-1307 USA
> +
> +use strict;
> +use warnings;
> +use C4::Context;
> +use C4::Koha;
> +use C4::SQLHelper qw( SearchInTable InsertInTable UpdateInTable
> DeleteInTable );
> +use Memoize;
> +
> +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
> +
> +BEGIN {
> +       # set the version for version checking
> +       $VERSION = 3.0.5;
> +       @ISA    = qw(Exporter);
> +       @EXPORT = qw(
> +           &GetIssuingRule
> +               &GetIssuingRulesByBranchCode
> +               &GetIssuingRules
> +               &AddIssuingRule
> +               &ModIssuingRule
> +               &DelIssuingRule
> +       );
> +}
> +
> +=head1 NAME
> +
> +C4::IssuingRules - Koha issuing rules module
> +
> +=head1 SYNOPSIS
> +
> +use C4::IssuingRules;
> +
> +=head1 DESCRIPTION
> +
> +The functions in this module deal with issuing rules.
> +
> +=head1 FUNCTIONS
> +
> +=head2 GetIssuingRule
> +
> +Compute the issuing rule for an itemtype, a borrower category and a
> branch.
> +Returns a hashref from the issuingrules table.
> +
> +my $rule = &GetIssuingRule($categorycode, $itemtype, $branchcode);
> +
> +The rules are applied from most specific to less specific, using the first
> found in this order:
> +    * same library, same patron type, same item type
> +    * same library, same patron type, default item type
> +    * same library, default patron type, same item type
> +    * same library, default patron type, default item type
> +    * default library, same patron type, same item type
> +    * default library, same patron type, default item type
> +    * default library, default patron type, same item type
> +    * default library, default patron type, default item type
> +
> +The values in the returned hashref are inherited from a more generic rules
> if undef.
> +
> +=cut
> +#Caching GetIssuingRule
> +memoize('GetIssuingRule');
> +
> +sub GetIssuingRule {
> +    my ( $categorycode, $itemtype, $branchcode ) = @_;
> +    $categorycode||="*";
> +    $itemtype||="*";
> +    $branchcode||="*";
> +
> +    # This configuration table defines the order of inheritance. We'll
> loop over it.
> +    my @attempts = (
> +        [ "*"          , "*"      , "*"         ],
> +        [ "*"          , $itemtype, "*"         ],
> +        [ $categorycode, "*"      , "*"         ],
> +        [ $categorycode, $itemtype, "*"         ],
> +        [ "*"          , "*"      , $branchcode ],
> +        [ "*"          , $itemtype, $branchcode ],
> +        [ $categorycode, "*"      , $branchcode ],
> +        [ $categorycode, $itemtype, $branchcode ],
> +    );
> +
> +    # This complex query returns a nested hashref, so we can access a rule
> using :
> +    # my $rule = $$rules{$categorycode}{$itemtype}{$branchcode};
> +    # this will be usefull in the inheritance computation code
> +    my $dbh = C4::Context->dbh;
> +    my $rules = $dbh->selectall_hashref(
> +        "SELECT * FROM issuingrules where branchcode IN ('*',?) and
> itemtype IN ('*', ?) and categorycode IN ('*',?)",
> +        ["branchcode", "itemtype", "categorycode"],
> +        undef,
> +        ( $branchcode, $itemtype, $categorycode )
> +    );
> +
> +    # This block is for inheritance. It loops over rules returned by the
> +    # previous query. If a value is found in a more specific rule, it
> replaces
> +    # the old value from the more generic rule.
> +    my $oldrule;
> +    for my $attempt ( @attempts ) {
> +        if ( my $rule = $$rules{@$attempt[2]}{@$attempt[1]}{@$attempt[0]}
> ) {
> +            if ( $oldrule ) {
> +                for ( keys %$oldrule ) {
> +                    if ( defined $rule->{$_} ) {
> +                        $oldrule->{$_} = $rule->{$_};
> +                    }
> +                }
> +            } else {
> +                $oldrule = $rule;
> +            }
> +        }
> +    }
> +    if($oldrule){
> +        return $oldrule;
> +    }else{
> +        return {
> +            'itemtype'          => $itemtype,
> +            'categorycode'      => $categorycode,
> +            'branchcode'        => $branchcode,
> +            'holdspickupdelay'  => 0,
> +       #     'maxissueqty'       => 0,
> +            'renewalsallowed'   => 0,
> +            'firstremind'       => 0,
> +            'accountsent'       => 0,
> +            'reservecharge'     => 0,
> +            'fine'              => 0,
> +            'restrictedtype'    => 0,
> +            'rentaldiscount'    => 0,
> +            'chargename'        => 0,
> +            'finedays'          => 0,
> +            'holdrestricted'    => 0,
> +            'allowonshelfholds' => 0,
> +            'reservesallowed'   => 0,
> +            'chargeperiod'      => 0,
> +       #     'issuelength'       => 0,
> +            'renewalperiod'     => 0,
> +        };
> +    }
> +}
> +
> +=head2 GetIssuingRulesByBranchCode
> +
> +  my @issuingrules = &GetIssuingRulesByBranchCode($branchcode);
> +
> +  Retruns a list of hashref from the issuingrules Koha table for a given
> +  branchcode.
> +  Each hashref will contain data from issuingrules plus human readable
> names of
> +  patron and item categories.
> +
> +=cut
> +
> +sub GetIssuingRulesByBranchCode {
> +    my $dbh = C4::Context->dbh;
> +    my $sth = $dbh->prepare("
> +        SELECT issuingrules.*, itemtypes.description AS humanitemtype,
> categories.description AS humancategorycode
> +        FROM issuingrules
> +        LEFT JOIN itemtypes
> +            ON (itemtypes.itemtype = issuingrules.itemtype)
> +        LEFT JOIN categories
> +            ON (categories.categorycode = issuingrules.categorycode)
> +        WHERE issuingrules.branchcode = ?
> +        ORDER BY humancategorycode, humanitemtype
> +    ");
> +    $sth->execute(shift);
> +
> +    my $res = $sth->fetchall_arrayref({});
> +
> +    return @$res;
> +}
> +
> +=head2 GetIssuingRules
> +
> +  my @issuingrules = &GetIssuingRules({
> +      branchcode   => $branch,
> +      categorycode => $input->param('categorycode'),
> +      itemtype     => $input->param('itemtype'),
> +  });
> +
> +  Get an issuing rule from Koha database.
> +  An alias for SearchInTable, see C4::SQLHelper for more help.
> +
> +=cut
> +
> +sub GetIssuingRules {
> +    my $res = SearchInTable('issuingrules', shift);
> +    return @$res;
> +}
> +
> +=head2 AddIssuingRule
> +
> +  my $issuingrule = {
> +      branchcode      => $branch,
> +      categorycode    => $input->param('categorycode'),
> +      itemtype        => $input->param('itemtype'),
> +      maxissueqty     => $maxissueqty,
> +      renewalsallowed => $input->param('renewalsallowed'),
> +      reservesallowed => $input->param('reservesallowed'),
> +      issuelength     => $input->param('issuelength'),
> +      fine            => $input->param('fine'),
> +      finedays        => $input->param('finedays'),
> +      firstremind     => $input->param('firstremind'),
> +      chargeperiod    => $input->param('chargeperiod'),
> +  };
> +
> +  &AddIssuingRule( $issuingrule );
> +
> +  Adds an issuing rule to Koha database.
> +  An alias for InsertInTable, see C4::SQLHelper for more help.
> +
> +=cut
> +
> +sub AddIssuingRule { InsertInTable('issuingrules',shift); }
> +
> +=head2 ModIssuingRule
> +
> +  &ModIssuingRule( $issuingrule );
> +
> +  Update an issuing rule of the Koha database.
> +  An alias for UpdateInTable, see C4::SQLHelper for more help.
> +
> +=cut
> +
> +sub ModIssuingRule { UpdateInTable('issuingrules',shift); }
> +
> +=head2 DelIssuingRule
> +
> +  DelIssuingRule({
> +      branchcode   => $branch,
> +      categorycode => $input->param('categorycode'),
> +      itemtype     => $input->param('itemtype'),
> +  });
> +
> +  Delete an issuing rule from Koha database.
> +  An alias for DeleteInTable, see C4::SQLHelper for more help.
> +
> +=cut
> +
> +sub DelIssuingRule { DeleteInTable('issuingrules',shift); }
> +
> +1;
> +
> +=head1 AUTHOR
> +
> +Koha Developement team <info at koha.org>
> +
> +Jean-André Santoni <jeanandre.santoni at biblibre.com>
> +
> +=cut
> diff --git a/C4/Overdues.pm b/C4/Overdues.pm
> index 032ca93..03b3d22 100644
> --- a/C4/Overdues.pm
> +++ b/C4/Overdues.pm
> @@ -23,6 +23,7 @@ use strict;
>  use Date::Calc qw/Today Date_to_Days/;
>  use Date::Manip qw/UnixDate/;
>  use C4::Circulation;
> +use C4::IssuingRules;
>  use C4::Context;
>  use C4::Accounts;
>  use C4::Log; # logaction
> @@ -71,9 +72,6 @@ BEGIN {
>        push @EXPORT, qw(
>         &GetIssuesIteminfo
>        );
> -    #
> -       # &GetIssuingRules - delete.
> -       # use C4::Circulation::GetIssuingRule instead.
>
>        # subs to move to Members.pm
>        push @EXPORT, qw(
> @@ -124,7 +122,7 @@ sub Getoverdues {
>    SELECT issues.*, items.itype as itemtype, items.homebranch,
> items.barcode
>      FROM issues
>  LEFT JOIN items       USING (itemnumber)
> -    WHERE date_due < CURDATE()
> +    WHERE DATE(date_due) < CURDATE()
>  ";
>     } else {
>         $statement = "
> @@ -132,7 +130,7 @@ LEFT JOIN items       USING (itemnumber)
>      FROM issues
>  LEFT JOIN items       USING (itemnumber)
>  LEFT JOIN biblioitems USING (biblioitemnumber)
> -    WHERE date_due < CURDATE()
> +    WHERE DATE(date_due) < CURDATE()
>  ";
>     }
>
> @@ -170,7 +168,7 @@ sub checkoverdues {
>          LEFT JOIN biblio      ON items.biblionumber     =
> biblio.biblionumber
>          LEFT JOIN biblioitems ON items.biblioitemnumber =
> biblioitems.biblioitemnumber
>             WHERE issues.borrowernumber  = ?
> -            AND   issues.date_due < CURDATE()"
> +            AND   DATE(issues.date_due) < CURDATE()"
>     );
>     # FIXME: SELECT * across 4 tables?  do we really need the marc AND
> marcxml blobs??
>     $sth->execute($borrowernumber);
> @@ -245,7 +243,7 @@ sub CalcFine {
>        my $daystocharge;
>        # get issuingrules (fines part will be used)
>     $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)",
> $bortype, $item->{'itemtype'}, $branchcode);
> -    my $data = C4::Circulation::GetIssuingRule($bortype,
> $item->{'itemtype'}, $branchcode);
> +    my $data = GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode);
>        if($difference) {
>                # if $difference is supplied, the difference has already
> been calculated, but we still need to adjust for the calendar.
>        # use copy-pasted functions from calendar module.  (deprecated --
> these functions will be removed from C4::Overdues ).
> @@ -269,7 +267,7 @@ sub CalcFine {
>     } else {
>         # a zero (or null)  chargeperiod means no charge.
>     }
> -       $amount = C4::Context->preference('maxFine')
> if(C4::Context->preference('maxFine') && ( $amount >
> C4::Context->preference('maxFine')));
> +    $amount = C4::Context->preference('MaxFine') if (
> C4::Context->preference('MaxFine') && ( $amount >
> C4::Context->preference('MaxFine') ) );
>        $debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)",
> $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
>     return ($amount, $data->{'chargename'}, $days_minus_grace,
> $daystocharge);
>     # FIXME: chargename is NEVER populated anywhere.
> @@ -585,7 +583,7 @@ Returns the replacement cost of the item with the given
> item number.
>
>  =cut
>
> -#'
> +
>  sub ReplacementCost {
>     my ($itemnum) = @_;
>     my $dbh       = C4::Context->dbh;
> @@ -604,60 +602,22 @@ sub ReplacementCost {
>
>  return the total of fine
>
> -C<$itemnum> is item number
> -
>  C<$borrowernumber> is the borrowernumber
>
> -=cut
> -
> +=cut
>
>  sub GetFine {
> -    my ( $itemnum, $borrowernumber ) = @_;
> +    my ( $borrowernumber ) = @_;
>     my $dbh   = C4::Context->dbh();
>     my $query = "SELECT sum(amountoutstanding) FROM accountlines
>     where accounttype like 'F%'
> -  AND amountoutstanding > 0 AND itemnumber = ? AND borrowernumber=?";
> +  AND amountoutstanding > 0 AND borrowernumber=?";
>     my $sth = $dbh->prepare($query);
> -    $sth->execute( $itemnum, $borrowernumber );
> +    $sth->execute( $borrowernumber );
>     my $data = $sth->fetchrow_hashref();
>     return ( $data->{'sum(amountoutstanding)'} );
>  }
>
> -
> -=head2 GetIssuingRules
> -
> -FIXME - This sub should be deprecated and removed.
> -It ignores branch and defaults.
> -
> -    $data = &GetIssuingRules($itemtype,$categorycode);
> -
> -Looks up for all issuingrules an item info
> -
> -C<$itemnumber> is a reference-to-hash whose keys are all of the fields
> -from the borrowers and categories tables of the Koha database. Thus,
> -
> -C<$categorycode> contains  information about borrowers category
> -
> -C<$data> contains all information about both the borrower and
> -category he or she belongs to.
> -=cut
> -
> -sub GetIssuingRules {
> -       warn "GetIssuingRules is deprecated: use GetIssuingRule from
> C4::Circulation instead.";
> -   my ($itemtype,$categorycode)=@_;
> -   my $dbh   = C4::Context->dbh();
> -   my $query=qq|SELECT *
> -        FROM issuingrules
> -        WHERE issuingrules.itemtype=?
> -            AND issuingrules.categorycode=?
> -        |;
> -    my $sth = $dbh->prepare($query);
> -    #  print $query;
> -    $sth->execute($itemtype,$categorycode);
> -    return $sth->fetchrow_hashref;
> -}
> -
> -
>  sub ReplacementCost2 {
>     my ( $itemnum, $borrowernumber ) = @_;
>     my $dbh   = C4::Context->dbh();
> @@ -956,7 +916,7 @@ returns a list of branch codes for branches with
> overdue rules defined.
>
>  sub GetBranchcodesWithOverdueRules {
>     my $dbh               = C4::Context->dbh;
> -    my $rqoverduebranches = $dbh->prepare("SELECT DISTINCT branchcode FROM
> overduerules WHERE delay1 IS NOT NULL AND branchcode <> ''");
> +    my $rqoverduebranches = $dbh->prepare("SELECT DISTINCT branchcode FROM
> overduerules WHERE delay1 IS NOT NULL ");
>     $rqoverduebranches->execute;
>     my @branches = map { shift @$_ } @{
> $rqoverduebranches->fetchall_arrayref };
>     return @branches;
> @@ -1029,7 +989,7 @@ sub GetOverduerules {
>
>  Check if the borrowers is already debarred
>
> -C<$debarredstatus> return 0 for not debarred and return 1 for debarred
> +C<$debarredstatus> return undef for not debarred and return end of debar
> date for debarred
>
>  C<$borrowernumber> contains the borrower number
>
> @@ -1043,32 +1003,35 @@ sub CheckBorrowerDebarred {
>         SELECT debarred
>         FROM borrowers
>         WHERE borrowernumber=?
> +        AND debarred > NOW()
>     |;
>     my $sth = $dbh->prepare($query);
>     $sth->execute($borrowernumber);
> -    my ($debarredstatus) = $sth->fetchrow;
> -    return ( $debarredstatus eq '1' ? 1 : 0 );
> +    my $debarredstatus= $sth->fetchrow;
> +    return $debarredstatus;
> +
>  }
>
>  =head2 UpdateBorrowerDebarred
>
> -    ($borrowerstatut) = &UpdateBorrowerDebarred($borrowernumber);
> +   ($borrowerstatut) = &UpdateBorrowerDebarred($borrowernumber, $todate);
>
>  update status of borrowers in borrowers table (field debarred)
>
>  C<$borrowernumber> borrower number
> +C<$todate> end of bare
>
>  =cut
>
>  sub UpdateBorrowerDebarred{
> -    my($borrowernumber) = @_;
> +    my($borrowernumber, $todate) = @_;
>     my $dbh = C4::Context->dbh;
>         my $query=qq|UPDATE borrowers
> -             SET debarred='1'
> +             SET debarred=?
>                      WHERE borrowernumber=?
>             |;
>     my $sth=$dbh->prepare($query);
> -        $sth->execute($borrowernumber);
> +        $sth->execute($todate, $borrowernumber);
>         $sth->finish;
>         return 1;
>  }
> diff --git a/C4/Reserves.pm b/C4/Reserves.pm
> index fcf9209..dd60a61 100644
> --- a/C4/Reserves.pm
> +++ b/C4/Reserves.pm
> @@ -22,6 +22,7 @@ package C4::Reserves;
>
>  use strict;
>  #use warnings; FIXME - Bug 2505
> +use Date::Calc qw( Add_Delta_Days Time_to_Date Today);
>  use C4::Context;
>  use C4::Biblio;
>  use C4::Members;
> @@ -32,10 +33,11 @@ use C4::Accounts;
>
>  # for _koha_notify_reserve
>  use C4::Members::Messaging;
> -use C4::Members qw();
> +use C4::Members ;
>  use C4::Letters;
>  use C4::Branch qw( GetBranchDetail );
>  use C4::Dates qw( format_date_in_iso );
> +use C4::IssuingRules;
>  use List::MoreUtils qw( firstidx );
>
>  use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
> @@ -91,11 +93,14 @@ BEGIN {
>     @EXPORT = qw(
>         &AddReserve
>
> +        &GetMaxPickupDelay
> +        &GetMaxPickupDate
>         &GetReservesFromItemnumber
>         &GetReservesFromBiblionumber
>         &GetReservesFromBorrowernumber
>         &GetReservesForBranch
>         &GetReservesToBranch
> +        &GetReservesControlBranch
>         &GetReserveCount
>         &GetReserveFee
>                &GetReserveInfo
> @@ -113,13 +118,16 @@ BEGIN {
>         &CheckReserves
>         &CanBookBeReserved
>        &CanItemBeReserved
> -        &CancelReserve
> -        &CancelExpiredReserves
> +      &CanHoldOnShelf
> +      &CancelReserve
> +      &CancelExpiredReserves
>
> -        &IsAvailableForItemLevelRequest
> -
> -        &AlterPriority
> -        &ToggleLowestPriority
> +      &IsAvailableForItemLevelRequest
> +
> +      &AlterPriority
> +      &ToggleLowestPriority
> +      &CanHoldMultipleItems
> +      &BorrowerHasReserve
>     );
>  }
>
> @@ -142,11 +150,17 @@ sub AddReserve {
>     my $const   = lc substr( $constraint, 0, 1 );
>     $resdate = format_date_in_iso( $resdate ) if ( $resdate );
>     $resdate = C4::Dates->today( 'iso' ) unless ( $resdate );
> +    my $item = C4::Items::GetItem($checkitem);
> +    my @maxPickupDate = GetMaxPickupDate($resdate, $borrowernumber,
> $item);
> +    my $maxpickupdate = sprintf( "%d-%02d-%02d", @maxPickupDate );
>     if ($expdate) {
>         $expdate = format_date_in_iso( $expdate );
> +        my @expdate = split("-", $expdate);
> +        $expdate = $maxpickupdate if Delta_Days(@expdate[ 0 .. 2 ],
> @maxPickupDate[ 0 .. 2 ]) < 0;
>     } else {
> -        undef $expdate; # make reserves.expirationdate default to null
> rather than '0000-00-00'
> +        $expdate = $maxpickupdate;
>     }
> +    undef $expdate if $resdate eq $maxpickupdate; # make
> reserves.expirationdate default to null rather than '0000-00-00'
>     if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) {
>        # Make room in reserves for this before those of a later reserve
> date
>        $priority = _ShiftPriorityByDateAndPriority( $biblionumber,
> $resdate, $priority );
> @@ -248,24 +262,27 @@ sub GetReservesFromBiblionumber {
>
>     # Find the desired items in the reserves
>     my $query = "
> -        SELECT  branchcode,
> -                timestamp AS rtimestamp,
> -                priority,
> -                biblionumber,
> -                borrowernumber,
> -                reservedate,
> -                constrainttype,
> -                found,
> -                itemnumber,
> -                reservenotes,
> -                expirationdate,
> -                lowestPriority
> +        SELECT  reserves.reservenumber,
> +                reserves.branchcode,
> +                reserves.timestamp AS rtimestamp,
> +                reserves.priority,
> +                reserves.biblionumber,
> +                reserves.borrowernumber,
> +                reserves.reservedate,
> +                reserves.constrainttype,
> +                reserves.found,
> +                reserves.itemnumber,
> +                reserves.reservenotes,
> +                reserves.expirationdate,
> +                reserves.lowestPriority,
> +                biblioitems.itemtype
>         FROM     reserves
> -        WHERE biblionumber = ? ";
> +        LEFT JOIN biblioitems ON biblioitems.biblionumber =
> reserves.biblionumber
> +        WHERE reserves.biblionumber = ? ";
>     unless ( $all_dates ) {
>         $query .= "AND reservedate <= CURRENT_DATE()";
>     }
> -    $query .= "ORDER BY priority";
> +    $query .= "ORDER BY reserves.priority";
>     my $sth = $dbh->prepare($query);
>     $sth->execute($biblionumber);
>     my @results;
> @@ -371,9 +388,40 @@ sub GetReservesFromBorrowernumber {
>     return @$data;
>  }
>
>  #-------------------------------------------------------------------------------------
> +sub BorrowerHasReserve {
> +    my ( $borrowernumber, $biblionumber, $itemnumber ) = @_;
> +    my $dbh   = C4::Context->dbh;
> +    my $sth;
> +
> +    if ( $biblionumber ) {
> +      $sth = $dbh->prepare("
> +            SELECT COUNT(*) AS hasReserve
> +            FROM   reserves
> +            WHERE  borrowernumber = ?
> +            AND    biblionumber = ?
> +            ORDER BY reservedate
> +        ");
> +      $sth->execute( $borrowernumber, $biblionumber );
> +    } elsif ( $itemnumber ) {
> +      $sth = $dbh->prepare("
> +            SELECT COUNT(*) AS hasReserve
> +            FROM   reserves
> +            WHERE  borrowernumber = ?
> +            AND    itemnumber = ?
> +            ORDER BY reservedate
> +        ");
> +      $sth->execute( $borrowernumber, $itemnumber );
> +    } else {
> +      return -1;
> +    }
> +
> +    my $data = $sth->fetchrow_hashref();
> +    return $data->{'hasReserve'};
> +}
> +
>  =head2 CanBookBeReserved
>
> -  $error = &CanBookBeReserved($borrowernumber, $biblionumber)
> +$error = &CanBookBeReserved($borrowernumber, $biblionumber)
>
>  =cut
>
> @@ -397,7 +445,7 @@ This function return 1 if an item can be issued by this
> borrower.
>
>  sub CanItemBeReserved{
>     my ($borrowernumber, $itemnumber) = @_;
> -
> +
>     my $dbh             = C4::Context->dbh;
>     my $allowedreserves = 0;
>
> @@ -405,7 +453,7 @@ sub CanItemBeReserved{
>     my $itype         = C4::Context->preference('item-level_itypes') ?
> "itype" : "itemtype";
>
>     # we retrieve borrowers and items informations #
> -    my $item     = GetItem($itemnumber);
> +    my $item     = C4::Items::GetItem($itemnumber);
>     my $borrower =
> C4::Members::GetMember('borrowernumber'=>$borrowernumber);
>
>     # we retrieve user rights on this itemtype and branchcode
> @@ -436,22 +484,31 @@ sub CanItemBeReserved{
>     my $branchfield  = "reserves.branchcode";
>
>     if( $controlbranch eq "ItemHomeLibrary" ){
> -        $branchfield = "items.homebranch";
> -        $branchcode = $item->{homebranch};
> +        my
> $field=C4::Context->preference("HomeOrHoldingBranch")||"homebranch";
> +        $branchfield = "items.$field";
> +        $branchcode = $item->{$field};
>     }elsif( $controlbranch eq "PatronLibrary" ){
>         $branchfield = "borrowers.branchcode";
>         $branchcode = $borrower->{branchcode};
>     }
>
> -    # we retrieve rights
> -    $sth->execute($categorycode, $itemtype, $branchcode);
> -    if(my $rights = $sth->fetchrow_hashref()){
> -        $itemtype        = $rights->{itemtype};
> -        $allowedreserves = $rights->{reservesallowed};
> +    # we retrieve user rights on this itemtype and branchcode
> +    my $issuingrule = GetIssuingRule($borrower->{categorycode},
> $item->{$itype}, $branchcode);
> +    return 0 if( defined $issuingrule->{reservesallowed} && not
> $issuingrule->{reservesallowed} );
> +
> +    # We retrieve the count of reserves allowed for this category code
> +    $issuingrule  = GetIssuingRule ($borrower->{categorycode}, "*", "*");
> +
> +    if($issuingrule){
> +        $itemtype        = $issuingrule->{itemtype};
> +        $allowedreserves = $issuingrule->{reservesallowed};
>     }else{
>         $itemtype = '*';
>     }
>
> +    return 0 if ($issuingrule->{reservesallowed}==0 ||
> +                ($issuingrule->{holdrestricted}== 1 && !($branchcode eq
> $borrower->{branchcode}))
> +                );
>     # we retrieve count
>
>     $querycount .= "AND $branchfield = ?";
> @@ -477,6 +534,106 @@ sub CanItemBeReserved{
>         return 0;
>     }
>  }
> +
> +=item GetMaxPickupDelay
> +
> +$resallowed = &GetMaxPickupDelay($borrowernumber, $itemnumber)
> +
> +this function return the number of allowed reserves.
> +
> +=cut
> +
> +sub GetMaxPickupDelay {
> +    my ($borrowernumber, $itemnumber) = @_;
> +
> +    my $dbh             = C4::Context->dbh;
> +    my $allowedreserves = 0;
> +
> +    my $itype         = C4::Context->preference('item-level_itypes') ?
> "itype" : "itemtype";
> +
> +    # we retrieve borrowers and items informations #
> +    my $item     = C4::Items::GetItem($itemnumber);
> +    my $borrower =
> C4::Members::GetMember('borrowernumber'=>$borrowernumber);
> +    my $controlbranch = GetReservesControlBranch($borrower,$item);
> +
> +    # we retrieve user rights on this itemtype and branchcode
> +    my $sth = $dbh->prepare("SELECT holdspickupdelay
> +                    FROM issuingrules
> +                    WHERE categorycode=?
> +                    AND itemtype=?
> +                    AND branchcode=?
> +                    AND holdspickupdelay IS NOT NULL"
> +                           );
> +
> +    my $itemtype     = $item->{$itype};
> +    my $borrowertype = $borrower->{categorycode};
> +    my $branchcode   = $controlbranch;
> +
> +    $sth->execute( $borrowertype, $itemtype, $branchcode );
> +    my $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( $borrowertype, "*", $branchcode );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( "*", $itemtype, $branchcode );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( "*", "*", $branchcode );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( $borrowertype, $itemtype, "*" );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( $borrowertype, "*", "*" );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( "*", $itemtype, "*" );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    $sth->execute( "*", "*", "*" );
> +    $pickupdelay = $sth->fetchrow_hashref;
> +    return $pickupdelay->{holdspickupdelay}
> +      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne
> 'NULL';
> +
> +    # if nothing found, return no rights
> +    return 0;
> +}
> +
> +=item GetMaxPickupDate
> +
> +$maxpickupdate = &GetMaxPickupDate($date);
> +
> +this function return the max pickup date.
> +(e.g. : the date after which the hold will be considered cancelled)
> +
> +=cut
> +
> +sub GetMaxPickupDate{
> +    my $inputdate=shift;
> +    my $borrowernumber=shift;
> +    my $item=shift;
> +    return unless $inputdate;
> +    my @date = split(/-/,$inputdate);
> +    my $delay = GetMaxPickupDelay($borrowernumber, $item->{'itemnumber'});
> +    ( @date ) =
> +      Add_Delta_Days( @date[0..2], $delay);
> +    return @date;
> +}
> +
>
>  #--------------------------------------------------------------------------------
>  =head2 GetReserveCount
>
> @@ -516,21 +673,22 @@ sub GetOtherReserves {
>     my $nextreservinfo;
>     my ( $restype, $checkreserves ) = CheckReserves($itemnumber);
>     if ($checkreserves) {
> -        my $iteminfo = GetItem($itemnumber);
> +        my $iteminfo = C4::Items::GetItem($itemnumber);
>         if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'}
> ) {
>             $messages->{'transfert'} = $checkreserves->{'branchcode'};
>             #minus priorities of others reservs
>             ModReserveMinusPriority(
>                 $itemnumber,
>                 $checkreserves->{'borrowernumber'},
> -                $iteminfo->{'biblionumber'}
> +                $iteminfo->{'biblionumber'},
> +                $checkreserves->{'reservenumber'}
>             );
>
>             #launch the subroutine dotransfer
>             C4::Items::ModItemTransfer(
>                 $itemnumber,
>                 $iteminfo->{'holdingbranch'},
> -                $checkreserves->{'branchcode'}
> +                $checkreserves->{'branchcode'},
>               ),
>               ;
>         }
> @@ -541,7 +699,8 @@ sub GetOtherReserves {
>             ModReserveMinusPriority(
>                 $itemnumber,
>                 $checkreserves->{'borrowernumber'},
> -                $iteminfo->{'biblionumber'}
> +                $iteminfo->{'biblionumber'},
> +                $checkreserves->{'reservenumber'}
>             );
>             ModReserveStatus($itemnumber,'W');
>         }
> @@ -655,6 +814,26 @@ sub GetReserveFee {
>     return $fee;
>  }
>
> +=head2 GetReservesControlBranch
> +
> +$branchcode = &GetReservesControlBranch($borrower, $item)
> +
> +Returns the branchcode to consider to check hold rules against
> +
> +=cut
> +sub GetReservesControlBranch{
> +    my ($borrower, $item) = @_;
> +    my $controlbranch = C4::Context->preference('ReservesControlBranch');
> +    my $hbr           =
> C4::Context->preference('HomeOrHoldingBranch')||"homebranch";
> +    my $branchcode="*";
> +    if($controlbranch eq "ItemHomeLibrary"){
> +        $branchcode = $item->{$hbr};
> +    } elsif($controlbranch eq "PatronLibrary"){
> +        $branchcode = $borrower->{'branchcode'};
> +    }
> +    return $branchcode;
> +}
> +
>  =head2 GetReservesToBranch
>
>   @transreserv = GetReservesToBranch( $frombranch );
> @@ -838,23 +1017,18 @@ sub CancelExpiredReserves {
>     $sth->execute();
>
>     while ( my $res = $sth->fetchrow_hashref() ) {
> -        CancelReserve( $res->{'biblionumber'}, '',
> $res->{'borrowernumber'} );
> +        CancelReserve( $res->{'reservenumber'}, $res->{'biblionumber'} );
>     }
>
>  }
>
>  =head2 CancelReserve
>
> -  &CancelReserve($biblionumber, $itemnumber, $borrowernumber);
> +  &CancelReserve( $reservenumber, $biblionumber );
>
>  Cancels a reserve.
>
> -Use either C<$biblionumber> or C<$itemnumber> to specify the item to
> -cancel, but not both: if both are given, C<&CancelReserve> does
> -nothing.
> -
> -C<$borrowernumber> is the borrower number of the patron on whose
> -behalf the book was reserved.
> +C<$reservenumber> is the unique key for the reserve to be canceled.
>
>  If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
>  priorities of the other people who are waiting on the book.
> @@ -862,9 +1036,14 @@ priorities of the other people who are waiting on the
> book.
>  =cut
>
>  sub CancelReserve {
> -    my ( $biblio, $item, $borr ) = @_;
> +    my ( $reservenumber, $biblio ) = @_;
>     my $dbh = C4::Context->dbh;
> -        if ( $item and $borr ) {
> +
> +    my $sth = $dbh->prepare('SELECT * FROM reserves WHERE reservenumber =
> ?');
> +    $sth->execute( $reservenumber );
> +    my $reserve = $sth->fetchrow_hashref();
> +
> +    if ( $reserve->{'found'} eq 'W' ) {
>         # removing a waiting reserve record....
>         # update the database...
>         my $query = "
> @@ -872,27 +1051,46 @@ sub CancelReserve {
>             SET    cancellationdate = now(),
>                    found            = Null,
>                    priority         = 0
> -            WHERE  itemnumber       = ?
> -             AND   borrowernumber   = ?
> +            WHERE  reservenumber   = ?
>         ";
>         my $sth = $dbh->prepare($query);
> -        $sth->execute( $item, $borr );
> -        $sth->finish;
> +        $sth->execute( $reservenumber );
> +
> +        # get reserve information to place into old_reserves
>         $query = "
>             INSERT INTO old_reserves
>             SELECT * FROM reserves
> -            WHERE  itemnumber       = ?
> -             AND   borrowernumber   = ?
> +            WHERE reservenumber     = ?
>         ";
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $item, $borr );
> +        $sth->execute( $reservenumber );
> +        my $holditem = $sth->fetchrow_hashref;
> +        my $insert_fields = '';
> +        my $value_fields = '';
> +        foreach my $column
> ('borrowernumber','reservedate','biblionumber','constrainttype','branchcode','notificationdate','reminderdate','cancellationdate','reservenotes','priority','found','itemnumber','waitingdate','expirationdate')
> {
> +          if (defined($holditem->{$column})) {
> +            if (length($insert_fields)) {
> +              $insert_fields .= ",$column";
> +              $value_fields .= ",\'$holditem->{$column}\'";
> +            }
> +            else {
> +              $insert_fields .= "$column";
> +              $value_fields .= "\'$holditem->{$column}\'";
> +            }
> +          }
> +        }
> +        $query = qq/
> +            INSERT INTO old_reserves ($insert_fields)
> +            VALUES ($value_fields)
> +        /;
> +        $sth = $dbh->prepare($query);
> +        $sth->execute();
>         $query = "
>             DELETE FROM reserves
> -            WHERE  itemnumber       = ?
> -             AND   borrowernumber   = ?
> +            WHERE  reservenumber   = ?
>         ";
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $item, $borr );
> +        $sth->execute( $reservenumber );
>     }
>     else {
>         # removing a reserve record....
> @@ -900,52 +1098,72 @@ sub CancelReserve {
>         my $priority;
>         my $query = qq/
>             SELECT priority FROM reserves
> -            WHERE biblionumber   = ?
> -              AND borrowernumber = ?
> +            WHERE reservenumber = ?
>               AND cancellationdate IS NULL
>               AND itemnumber IS NULL
>         /;
>         my $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borr );
> +        $sth->execute( $reservenumber );
>         ($priority) = $sth->fetchrow_array;
>         $sth->finish;
>         $query = qq/
>             UPDATE reserves
>             SET    cancellationdate = now(),
>                    found            = Null,
> -                   priority         = 0
> -            WHERE  biblionumber     = ?
> -              AND  borrowernumber   = ?
> +                   priority         = 0,
> +                   expirationdate   = NULL
> +            WHERE  reservenumber   = ?
>         /;
>
>         # update the database, removing the record...
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borr );
> -        $sth->finish;
> +        $sth->execute( $reservenumber );
>
>         $query = qq/
>             INSERT INTO old_reserves
>             SELECT * FROM reserves
> -            WHERE  biblionumber     = ?
> -              AND  borrowernumber   = ?
> +            WHERE reservenumber   = ?
> +        /;
> +        $sth = $dbh->prepare($query);
> +        $sth->execute( $reservenumber );
> +        my $holditem = $sth->fetchrow_hashref;
> +
> +        my $insert_fields = '';
> +        my $value_fields = '';
> +        foreach my $column
> ('borrowernumber','reservedate','biblionumber','constrainttype','branchcode','notificationdate','reminderdate','cancellationdate','reservenotes','priority','found','itemnumber','waitingdate','expirationdate')
> {
> +          if (defined($holditem->{$column})) {
> +            if (length($insert_fields)) {
> +              $insert_fields .= ",$column";
> +              $value_fields .= ",\'$holditem->{$column}\'";
> +            }
> +            else {
> +              $insert_fields .= "$column";
> +              $value_fields .= "\'$holditem->{$column}\'";
> +            }
> +          }
> +        }
> +        $query = qq/
> +            INSERT INTO old_reserves ($insert_fields)
> +            VALUES ($value_fields)
>         /;
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borr );
> +        $sth->execute();
>
>         $query = qq/
>             DELETE FROM reserves
> -            WHERE  biblionumber     = ?
> -              AND  borrowernumber   = ?
> +            WHERE  reservenumber   = ?
>         /;
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borr );
> +        $sth->execute( $reservenumber );
>
>         # now fix the priority on the others....
> -        _FixPriority( $biblio, $borr );
> +        _FixPriority( '', '', $priority,'', $reservenumber );
>     }
>  }
>
> -=head2 ModReserve
> +=item ModReserve
> +
> +=over 4
>
>   ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber])
>
> @@ -978,52 +1196,48 @@ itemnumber and supplying itemnumber.
>
>  sub ModReserve {
>     #subroutine to update a reserve
> -    my ( $rank, $biblio, $borrower, $branch , $itemnumber) = @_;
> +    my ( $rank, $biblio, $borrower, $branch , $itemnumber, $reservenumber)
> = @_;
>      return if $rank eq "W";
>      return if $rank eq "n";
>     my $dbh = C4::Context->dbh;
>     if ( $rank eq "del" ) {
>         my $query = qq/
>             UPDATE reserves
> -            SET    cancellationdate=now()
> -            WHERE  biblionumber   = ?
> -             AND   borrowernumber = ?
> +            SET    cancellationdate=now(),
> +                   expirationdate = NULL
> +            WHERE  reservenumber   = ?
>         /;
>         my $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borrower );
> +        $sth->execute( $reservenumber );
>         $sth->finish;
>         $query = qq/
>             INSERT INTO old_reserves
> -            SELECT *
> -            FROM   reserves
> -            WHERE  biblionumber   = ?
> -             AND   borrowernumber = ?
> +            SELECT * FROM reserves
> +            WHERE  reservenumber   = ?
>         /;
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borrower );
> +        $sth->execute( $reservenumber );
>         $query = qq/
>             DELETE FROM reserves
> -            WHERE  biblionumber   = ?
> -             AND   borrowernumber = ?
> +            WHERE  reservenumber   = ?
>         /;
>         $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borrower );
> +        $sth->execute( $reservenumber );
>
>     }
>     elsif ($rank =~ /^\d+/ and $rank > 0) {
>         my $query = qq/
>         UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = ?,
> found = NULL, waitingdate = NULL
> -            WHERE biblionumber   = ?
> -             AND borrowernumber = ?
> +            WHERE reservenumber = ?
>         /;
>         my $sth = $dbh->prepare($query);
> -        $sth->execute( $rank, $branch,$itemnumber, $biblio, $borrower);
> +        $sth->execute( $rank, $branch, $itemnumber, $reservenumber );
>         $sth->finish;
> -        _FixPriority( $biblio, $borrower, $rank);
> +        _FixPriority( $biblio, $borrower, $rank, '', $reservenumber);
>     }
>  }
>
> -=head2 ModReserveFill
> +=item ModReserveFill
>
>   &ModReserveFill($reserve);
>
> @@ -1042,16 +1256,17 @@ sub ModReserveFill {
>     my $biblionumber = $res->{'biblionumber'};
>     my $borrowernumber    = $res->{'borrowernumber'};
>     my $resdate = $res->{'reservedate'};
> +    my $resnumber      = $res->{'reservenumber'};
>
>     # get the priority on this record....
>     my $priority;
>     my $query = "SELECT priority
>                  FROM   reserves
> -                 WHERE  biblionumber   = ?
> -                  AND   borrowernumber = ?
> +                 WHERE  borrowernumber   = ?
> +                  AND   reservenumber  = ?
>                   AND   reservedate    = ?";
>     my $sth = $dbh->prepare($query);
> -    $sth->execute( $biblionumber, $borrowernumber, $resdate );
> +    $sth->execute( $resnumber, $borrowernumber, $resdate );
>     ($priority) = $sth->fetchrow_array;
>     $sth->finish;
>
> @@ -1059,35 +1274,35 @@ sub ModReserveFill {
>     $query = "UPDATE reserves
>                   SET    found            = 'F',
>                          priority         = 0
> -                 WHERE  biblionumber     = ?
> +                 WHERE  reservenumber     = ?
>                     AND reservedate      = ?
>                     AND borrowernumber   = ?
>                 ";
>     $sth = $dbh->prepare($query);
> -    $sth->execute( $biblionumber, $resdate, $borrowernumber );
> +    $sth->execute( $resnumber, $resdate, $borrowernumber );
>     $sth->finish;
>
>     # move to old_reserves
>     $query = "INSERT INTO old_reserves
>                  SELECT * FROM reserves
> -                 WHERE  biblionumber     = ?
> +                 WHERE  reservenumber    = ?
>                     AND reservedate      = ?
>                     AND borrowernumber   = ?
>                 ";
>     $sth = $dbh->prepare($query);
> -    $sth->execute( $biblionumber, $resdate, $borrowernumber );
> +    $sth->execute( $resnumber, $resdate, $borrowernumber );
>     $query = "DELETE FROM reserves
> -                 WHERE  biblionumber     = ?
> +                 WHERE  reservenumber    = ?
>                     AND reservedate      = ?
>                     AND borrowernumber   = ?
>                 ";
>     $sth = $dbh->prepare($query);
> -    $sth->execute( $biblionumber, $resdate, $borrowernumber );
> +    $sth->execute( $resnumber, $resdate, $borrowernumber );
>
>     # now fix the priority on the others (if the priority wasn't
>     # already sorted!)....
>     unless ( $priority == 0 ) {
> -        _FixPriority( $biblionumber, $borrowernumber );
> +        _FixPriority( $priority, $biblionumber,undef,undef,
> $res->{reservenumber} );
>     }
>  }
>
> @@ -1104,7 +1319,6 @@ $newstatus is the new status.
>  =cut
>
>  sub ModReserveStatus {
> -
>     #first : check if we have a reservation for this item .
>     my ($itemnumber, $newstatus) = @_;
>     my $dbh          = C4::Context->dbh;
> @@ -1138,9 +1352,8 @@ take care of the waiting status
>  =cut
>
>  sub ModReserveAffect {
> -    my ( $itemnumber, $borrowernumber,$transferToDo ) = @_;
> +    my ( $itemnumber, $borrowernumber,$transferToDo, $reservenumber ) =
> @_;
>     my $dbh = C4::Context->dbh;
> -
>     # we want to attach $itemnumber to $borrowernumber, find the
> biblionumber
>     # attached to $itemnumber
>     my $sth = $dbh->prepare("SELECT biblionumber FROM items WHERE
> itemnumber=?");
> @@ -1158,27 +1371,52 @@ sub ModReserveAffect {
>     $query = "
>         UPDATE reserves
>         SET    priority = 0,
> -               itemnumber = ?,
> -               found = 'T'
> -        WHERE borrowernumber = ?
> -          AND biblionumber = ?
> +               itemnumber = ?
> +        WHERE reservenumber = ?
>     ";
>     }
>     else {
>     # affect the reserve to Waiting as well.
> -    $query = "
> -        UPDATE reserves
> -        SET     priority = 0,
> -                found = 'W',
> -                waitingdate=now(),
> -                itemnumber = ?
> -        WHERE borrowernumber = ?
> -          AND biblionumber = ?
> -    ";
> +      my $holdperiod = C4::Context->preference('ReservesMaxPickUpDelay');
> +      if ((!defined($holdperiod)) || ($holdperiod eq '') || ($holdperiod
> == 0)) {
> +        $query = "
> +            UPDATE reserves
> +            SET     priority = 0,
> +                    found = 'W',
> +                    waitingdate=now(),
> +                    itemnumber = ?
> +        WHERE reservenumber = ?
> +        ";
> +      }
> +      else {
> +        my ($holdexpyear,$holdexpmonth,$holdexpday) = Today();
> +        my $holdstartdate = C4::Dates->new(sprintf
> "%02d/%02d/%04d",$holdexpmonth,$holdexpday,$holdexpyear, 'us');
> +
> +        # Grab branch for calendar purposes
> +        $sth = $dbh->prepare("SELECT branchcode FROM reserves WHERE
> borrowernumber=? AND biblionumber=?");
> +        $sth->execute($borrowernumber,$biblionumber);
> +        my ($branch) = $sth->fetchrow;
> +
> +        # Check to see if hold expiration date falls on a closed library
> day.
> +        # Note the useDaysMode syspref will need to be set to Calendar for
> +        # the code to advance to the next non-closed day.
> +        my $calendar = C4::Calendar->new( branchcode => $branch);
> +        my $holdexpdate  = $calendar->addDate($holdstartdate,
> $holdperiod);
> +        my $sqlexpdate = $holdexpdate->output('iso');
> +        $query = "
> +            UPDATE reserves
> +            SET     priority = 0,
> +                    found = 'W',
> +                    waitingdate=now(),
> +                    itemnumber = ?,
> +                    expirationdate='$sqlexpdate'
> +        WHERE reservenumber = ?
> +        ";
> +      }
>     }
>     $sth = $dbh->prepare($query);
> -    $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
> -    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if
> ( !$transferToDo && !$already_on_shelf );
> +    $sth->execute( $itemnumber, $reservenumber );
> +    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber,
> $reservenumber ) if ( !$transferToDo && !$already_on_shelf );
>
>     if ( C4::Context->preference("ReturnToShelvingCart") ) {
>       CartToShelf( $itemnumber );
> @@ -1218,23 +1456,21 @@ Reduce the values of queuded list
>  =cut
>
>  sub ModReserveMinusPriority {
> -    my ( $itemnumber, $borrowernumber, $biblionumber ) = @_;
> -
> +    my ( $itemnumber, $borrowernumber, $biblionumber, $reservenumber ) =
> @_;
>     #first step update the value of the first person on reserv
>     my $dbh   = C4::Context->dbh;
>     my $query = "
>         UPDATE reserves
>         SET    priority = 0 , itemnumber = ?
> -        WHERE  borrowernumber=?
> -          AND  biblionumber=?
> +        WHERE  reservenumber=?
>     ";
>     my $sth_upd = $dbh->prepare($query);
> -    $sth_upd->execute( $itemnumber, $borrowernumber, $biblionumber );
> +    $sth_upd->execute( $itemnumber, $reservenumber );
>     # second step update all others reservs
> -    _FixPriority($biblionumber, $borrowernumber, '0');
> +    _FixPriority($biblionumber, $borrowernumber, '0', '', $reservenumber);
>  }
>
> -=head2 GetReserveInfo
> +=item GetReserveInfo
>
>   &GetReserveInfo($borrowernumber,$biblionumber);
>
> @@ -1319,7 +1555,7 @@ and canreservefromotherbranches.
>  sub IsAvailableForItemLevelRequest {
>     my $itemnumber = shift;
>
> -    my $item = GetItem($itemnumber);
> +    my $item = C4::Items::GetItem($itemnumber);
>
>     # must check the notforloan setting of the itemtype
>     # FIXME - a lot of places in the code do this
> @@ -1354,10 +1590,10 @@ sub IsAvailableForItemLevelRequest {
>                                $notforloan_per_itemtype;
>
>
> -    if (C4::Context->preference('AllowOnShelfHolds')) {
> +    if (CanHoldOnShelf($itemnumber)) {
>         return $available_per_item;
>     } else {
> -        return ($available_per_item and ($item->{onloan} or
> GetReserveStatus($itemnumber) eq "W"));
> +        return ($available_per_item and ($item->{onloan} or
> GetReserveStatus($itemnumber) eq "W"));
>     }
>  }
>
> @@ -1385,15 +1621,15 @@ sub AlterPriority {
>
>       my $priority = $reserve->{'priority'};
>       $priority = $where eq 'up' ? $priority - 1 : $priority + 1;
> -      _FixPriority( $biblionumber, $borrowernumber, $priority )
> +      _FixPriority( $biblionumber, $borrowernumber, $priority
> ,undef,$reserve->{reservenumber})
>
>     } elsif ( $where eq 'top' ) {
>
> -      _FixPriority( $biblionumber, $borrowernumber, '1' )
> +      _FixPriority( $biblionumber, $borrowernumber,
> '1',undef,$reserve->{reservenumber} )
>
>     } elsif ( $where eq 'bottom' ) {
>
> -      _FixPriority( $biblionumber, $borrowernumber, '999999' )
> +        _FixPriority( $biblionumber, $borrowernumber,
> '999999',undef,$reserve->{reservenumber} )
>
>     }
>  }
> @@ -1416,18 +1652,50 @@ sub ToggleLowestPriority {
>          WHERE biblionumber = ?
>          AND borrowernumber = ?"
>     );
> -    $sth->execute(
> -        $biblionumber,
> -        $borrowernumber,
> -    );
> +    $sth->execute( $biblionumber, $borrowernumber, );
>     $sth->finish;
>
>     _FixPriority( $biblionumber, $borrowernumber, '999999' );
>  }
>
> +=head2 CanHoldOnShelf
> +
> +my $canhold = &CanHoldOnShelf($itemnumber);
> +
> + Check if a book can be hold on shelf.
> +
> +=cut
> +
> +sub CanHoldOnShelf {
> +    my ($itemnumber) = @_;
> +
> +    my $item = C4::Items::GetItem($itemnumber);
> +    my $itemtype = C4::Context->preference('item-level_itypes');
> +    $itemtype = $itemtype ? $item->{itype} : $item->{itemtype} ;
> +    my $branch = $item->{C4::Context->preference('HomeOrHoldingBranch')};
> +
> +    my $issuingrule = GetIssuingRule('*', $itemtype, $branch);
> +    return $issuingrule->{allowonshelfholds};
> +
> +}
> +
> +sub CanHoldMultipleItems {
> +  my ( $itemtype ) = @_;
> +
> +  my @multi_itemtypes = split( / /,
> C4::Context->preference('AllowMultipleHoldsPerBib') );
> +  for my $mtype ( @multi_itemtypes ) {
> +    if ( $itemtype eq $mtype ) {
> +      return 1;
> +    }
> +  }
> +
> +  return 0;
> +}
> +
>  =head2 _FixPriority
> +>>>>>>> [MT2355] Ergonomy improvement in smart rule management
>
> -  &_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank);
>
> +&_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank,$reservenumber);
>
>  Only used internally (so don't export it)
>  Changed how this functions works #
> @@ -1439,7 +1707,7 @@ in new priority rank
>  =cut
>
>  sub _FixPriority {
> -    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank ) = @_;
> +    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank,
> $reservenumber ) = @_;
>     my $dbh = C4::Context->dbh;
>      if ( $rank eq "del" ) {
>          CancelReserve( $biblio, undef, $borrowernumber );
> @@ -1450,12 +1718,11 @@ sub _FixPriority {
>         my $query = qq/
>             UPDATE reserves
>             SET    priority = 0
> -            WHERE biblionumber = ?
> -              AND borrowernumber = ?
> -              AND found IN ('W', 'T')
> +            WHERE reservenumber = ?
> +              AND found IN ('W',"T")
>         /;
>         my $sth = $dbh->prepare($query);
> -        $sth->execute( $biblio, $borrowernumber );
> +        $sth->execute( $reservenumber );
>     }
>     my @priority;
>     my @reservedates;
> @@ -1466,7 +1733,7 @@ sub _FixPriority {
>        # This is wrong a waiting reserve has W set
>        # The assumption that having an itemnumber set means waiting is
> wrong and should be corrected any place it occurs
>     my $query = qq/
> -        SELECT borrowernumber, reservedate, constrainttype
> +        SELECT borrowernumber, reservedate, constrainttype, reservenumber
>         FROM   reserves
>         WHERE  biblionumber   = ?
>           AND  ((found <> 'W' AND found <> 'T') or found is NULL)
> @@ -1501,16 +1768,15 @@ sub _FixPriority {
>     $query = "
>             UPDATE reserves
>             SET    priority = ?
> -                WHERE  biblionumber = ?
> -                 AND borrowernumber   = ?
> +                WHERE  reservenumber = ?
>                  AND reservedate = ?
>          AND found IS NULL
>     ";
>     $sth = $dbh->prepare($query);
>     for ( my $j = 0 ; $j < @priority ; $j++ ) {
>         $sth->execute(
> -            $j + 1, $biblio,
> -            $priority[$j]->{'borrowernumber'},
> +            $j + 1,
> +            $priority[$j]->{'reservenumber'},
>             $priority[$j]->{'reservedate'}
>         );
>         $sth->finish;
> @@ -1550,15 +1816,16 @@ sub _Findgroupreserve {
>     # TODO: consolidate at least the SELECT portion of the first 2 queries
> to a common $select var.
>     # check for exact targetted match
>     my $item_level_target_query = qq/
> -        SELECT reserves.biblionumber        AS biblionumber,
> -               reserves.borrowernumber      AS borrowernumber,
> -               reserves.reservedate         AS reservedate,
> -               reserves.branchcode          AS branchcode,
> -               reserves.cancellationdate    AS cancellationdate,
> -               reserves.found               AS found,
> -               reserves.reservenotes        AS reservenotes,
> -               reserves.priority            AS priority,
> -               reserves.timestamp           AS timestamp,
> +        SELECT reserves.reservenumber AS reservenumber,
> +               reserves.biblionumber AS biblionumber,
> +               reserves.borrowernumber AS borrowernumber,
> +               reserves.reservedate AS reservedate,
> +               reserves.branchcode AS branchcode,
> +               reserves.cancellationdate AS cancellationdate,
> +               reserves.found AS found,
> +               reserves.reservenotes AS reservenotes,
> +               reserves.priority AS priority,
> +               reserves.timestamp AS timestamp,
>                biblioitems.biblioitemnumber AS biblioitemnumber,
>                reserves.itemnumber          AS itemnumber
>         FROM reserves
> @@ -1580,15 +1847,16 @@ sub _Findgroupreserve {
>
>     # check for title-level targetted match
>     my $title_level_target_query = qq/
> -        SELECT reserves.biblionumber        AS biblionumber,
> -               reserves.borrowernumber      AS borrowernumber,
> -               reserves.reservedate         AS reservedate,
> -               reserves.branchcode          AS branchcode,
> -               reserves.cancellationdate    AS cancellationdate,
> -               reserves.found               AS found,
> -               reserves.reservenotes        AS reservenotes,
> -               reserves.priority            AS priority,
> -               reserves.timestamp           AS timestamp,
> +        SELECT reserves.reservenumber AS reservenumber,
> +               reserves.biblionumber AS biblionumber,
> +               reserves.borrowernumber AS borrowernumber,
> +               reserves.reservedate AS reservedate,
> +               reserves.branchcode AS branchcode,
> +               reserves.cancellationdate AS cancellationdate,
> +               reserves.found AS found,
> +               reserves.reservenotes AS reservenotes,
> +               reserves.priority AS priority,
> +               reserves.timestamp AS timestamp,
>                biblioitems.biblioitemnumber AS biblioitemnumber,
>                reserves.itemnumber          AS itemnumber
>         FROM reserves
> @@ -1609,15 +1877,16 @@ sub _Findgroupreserve {
>     return @results if @results;
>
>     my $query = qq/
> -        SELECT reserves.biblionumber               AS biblionumber,
> -               reserves.borrowernumber             AS borrowernumber,
> -               reserves.reservedate                AS reservedate,
> -               reserves.branchcode                 AS branchcode,
> -               reserves.cancellationdate           AS cancellationdate,
> -               reserves.found                      AS found,
> -               reserves.reservenotes               AS reservenotes,
> -               reserves.priority                   AS priority,
> -               reserves.timestamp                  AS timestamp,
> +        SELECT reserves.reservenumber AS reservenumber,
> +               reserves.biblionumber AS biblionumber,
> +               reserves.borrowernumber AS borrowernumber,
> +               reserves.reservedate AS reservedate,
> +               reserves.branchcode AS branchcode,
> +               reserves.cancellationdate AS cancellationdate,
> +               reserves.found AS found,
> +               reserves.reservenotes AS reservenotes,
> +               reserves.priority AS priority,
> +               reserves.timestamp AS timestamp,
>                reserveconstraints.biblioitemnumber AS biblioitemnumber,
>                reserves.itemnumber                 AS itemnumber
>         FROM reserves
> @@ -1649,30 +1918,29 @@ ModReserveAffect, _not_ ModReserveFill)
>  =cut
>
>  sub _koha_notify_reserve {
> -    my ($itemnumber, $borrowernumber, $biblionumber) = @_;
> +    my ($itemnumber, $borrowernumber, $biblionumber, $reservenumber) = @_;
>
> -    my $dbh = C4::Context->dbh;
> -    my $borrower = C4::Members::GetMember(borrowernumber =>
> $borrowernumber);
> +    my $dbh      = C4::Context->dbh;
> +    my $borrower = C4::Members::GetMember( 'borrowernumber'=>
> $borrowernumber );
>     my $letter_code;
>     my $print_mode = 0;
>     my $messagingprefs;
> -    if ( $borrower->{'email'} || $borrower->{'smsalertnumber'} ) {
> +    if ( C4::Members::GetFirstValidEmailAddress($borrowernumber) ||
> $borrower->{'smsalertnumber'} ) {
>         $messagingprefs = C4::Members::Messaging::GetMessagingPreferences(
> { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } );
>
>         return if ( !defined( $messagingprefs->{'letter_code'} ) );
>         $letter_code = $messagingprefs->{'letter_code'};
>     } else {
> -        $letter_code = 'HOLD_PRINT';
> +        $letter_code = 'HOLD';
>         $print_mode = 1;
>     }
>
>     my $sth = $dbh->prepare("
>         SELECT *
>         FROM   reserves
> -        WHERE  borrowernumber = ?
> -            AND biblionumber = ?
> +        WHERE  reservenumber = ?
>     ");
> -    $sth->execute( $borrowernumber, $biblionumber );
> +    $sth->execute( $reservenumber );
>     my $reserve = $sth->fetchrow_hashref;
>     my $branch_details = GetBranchDetail( $reserve->{'branchcode'} );
>
> @@ -1685,6 +1953,7 @@ sub _koha_notify_reserve {
>     C4::Letters::parseletter( $letter, 'borrowers', $borrowernumber );
>     C4::Letters::parseletter( $letter, 'biblio', $biblionumber );
>     C4::Letters::parseletter( $letter, 'reserves', $borrowernumber,
> $biblionumber );
> +    C4::Letters::parseletter( $letter, 'items',  $itemnumber );
>
>     if ( $reserve->{'itemnumber'} ) {
>         C4::Letters::parseletter( $letter, 'items',
> $reserve->{'itemnumber'} );
> diff --git a/admin/branch_transfer_limits.pl b/admin/
> branch_transfer_limits.pl
> index 1b89efb..7028a90 100755
> --- a/admin/branch_transfer_limits.pl
> +++ b/admin/branch_transfer_limits.pl
> @@ -83,13 +83,13 @@ while ( my $row = $sth->fetchrow_hashref ) {
>
>  ## If Form Data Passed, Update the Database
>  if ( $input->param('updateLimits') ) {
> -       DeleteBranchTransferLimits();
> +       DeleteBranchTransferLimits($branchcode);
>
>        foreach my $code ( @codes ) {
> -               foreach my $toBranch ( @branchcodes ) {
> -                       my $isSet = not $input->param( $code . "_" .
> $toBranch);
> +               foreach my $fromBranch ( @branchcodes ) {
> +                       my $isSet = not $input->param( $code . "_" .
> $fromBranch);
>                        if ( $isSet ) {
> -                           CreateBranchTransferLimit( $toBranch,
> $branchcode, $code );
> +                           CreateBranchTransferLimit( $branchcode,
> $fromBranch, $code );
>                        }
>                }
>        }
> @@ -107,18 +107,18 @@ my $branchcount = scalar(@branchcode_loop);
>  ## Build the default data
>  my @codes_loop;
>  foreach my $code ( @codes ) {
> -       my @to_branch_loop;
> +       my @from_branch_loop;
>        my %row_data;
>        $row_data{ code } = $code;
> -       $row_data{ to_branch_loop } = \@to_branch_loop;
> -       foreach my $toBranch ( @branchcodes ) {
> +       $row_data{ from_branch_loop } = \@from_branch_loop;
> +       foreach my $fromBranch ( @branchcodes ) {
>                my %row_data;
> -                my $isChecked = IsBranchTransferAllowed( $toBranch,
> $branchcode, $code );
> +        my $isChecked = IsBranchTransferAllowed( $branchcode, $fromBranch,
> $code );
>                $row_data{ code }         = $code;
> -               $row_data{ toBranch }     = $toBranch;
> +               $row_data{ fromBranch }     = $fromBranch;
>                $row_data{ isChecked }    = $isChecked;
> -               $row_data{ toBranchname } = GetBranchName($toBranch);
> -               push( @to_branch_loop, \%row_data );
> +               $row_data{ fromBranchname } = GetBranchName($fromBranch);
> +               push( @from_branch_loop, \%row_data );
>        }
>
>        push( @codes_loop, \%row_data );
> diff --git a/admin/smart-rules-service.pl b/admin/smart-rules-service.pl
> new file mode 100755
> index 0000000..3fca0ee
> --- /dev/null
> +++ b/admin/smart-rules-service.pl
> @@ -0,0 +1,59 @@
> +#!/usr/bin/perl
> +
> +# 2009 BibLibre <jeanandre.santoni at biblibre.com>
> +
> +# This file is part of Koha.
> +#
> +# Koha is free software; you can redistribute it and/or modify it under
> the
> +# terms of the GNU General Public License as published by the Free
> Software
> +# Foundation; either version 2 of the License, or (at your option) any
> later
> +# version.
> +#
> +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> FITNESS FOR
> +# A PARTICULAR PURPOSE.  See the GNU General Public License for more
> details.
> +#
> +# You should have received a copy of the GNU General Public License along
> with
> +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple
> Place,
> +# Suite 330, Boston, MA  02111-1307 USA
> +#
> +
> +use CGI;
> +use C4::Auth;
> +use C4::IssuingRules;
> +
> +my $cgi = CGI->new;
> +
> +# get the status of the user, this will check his credentials and rights
> +my ($status, $cookie, $sessionId) = C4::Auth::check_api_auth($cgi, undef);
> +
> +my $result;
> +
> +if ($status eq 'ok') { # if authentication is ok
> +
> +    # Get the POST data
> +    my $branchcode   = $cgi->param('branchcode');
> +    my $categorycode = $cgi->param('categorycode');
> +    my $itemtype     = $cgi->param('itemtype');
> +    my $varname      = $cgi->param('varname');
> +    my $inputvalue   = $cgi->param('inputvalue') eq '' ? undef :
> $cgi->param('inputvalue');
> +
> +    # Modify the existing rule
> +    ModIssuingRule({
> +        branchcode   => $branchcode,
> +        categorycode => $categorycode,
> +        itemtype     => $itemtype,
> +        $varname     => $inputvalue,
> +    });
> +
> +    # Compute inheritance, and return the new value;
> +    my $rule = GetIssuingRule($categorycode, $itemtype, $branchcode);
> +
> +    $result = $rule->{$varname};
> +} else {
> +    $result = 'Fail';
> +}
> +
> +print CGI::header('-type'=>'text/plain', '-charset'=>'utf-8');
> +print $result;
> +
> diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl
> index fdd9b91..72535b9 100755
> --- a/admin/smart-rules.pl
> +++ b/admin/smart-rules.pl
> @@ -25,317 +25,32 @@ use C4::Output;
>  use C4::Auth;
>  use C4::Koha;
>  use C4::Debug;
> -use C4::Branch; # GetBranches
> +use C4::Branch;
> +use C4::IssuingRules;
> +use C4::Circulation;
>
>  my $input = new CGI;
>  my $dbh = C4::Context->dbh;
>
> -# my $flagsrequired;
> -# $flagsrequired->{circulation}=1;
> -my ($template, $loggedinuser, $cookie)
> -    = get_template_and_user({template_name => "admin/smart-rules.tmpl",
> -                            query => $input,
> -                            type => "intranet",
> -                            authnotrequired => 0,
> -                            flagsrequired => {parameters => 1},
> -                            debug => 1,
> -                            });
> -
> -my $type=$input->param('type');
> -my $branch = $input->param('branch') || ( C4::Branch::onlymine() ? (
> C4::Branch::mybranch() || '*' ) : '*' );
> -my $op = $input->param('op');
> -
> -if ($op eq 'delete') {
> -    my $itemtype     = $input->param('itemtype');
> -    my $categorycode = $input->param('categorycode');
> -    $debug and warn "deleting $1 $2 $branch";
> -
> -    my $sth_Idelete = $dbh->prepare("delete from issuingrules where
> branchcode=? and categorycode=? and itemtype=?");
> -    $sth_Idelete->execute($branch, $categorycode, $itemtype);
> -}
> -elsif ($op eq 'delete-branch-cat') {
> -    my $categorycode  = $input->param('categorycode');
> -    if ($branch eq "*") {
> -        if ($categorycode eq "*") {
> -            my $sth_delete = $dbh->prepare("DELETE FROM
> default_circ_rules");
> -            $sth_delete->execute();
> -        } else {
> -            my $sth_delete = $dbh->prepare("DELETE FROM
> default_borrower_circ_rules
> -                                            WHERE categorycode = ?");
> -            $sth_delete->execute($categorycode);
> -        }
> -    } elsif ($categorycode eq "*") {
> -        my $sth_delete = $dbh->prepare("DELETE FROM
> default_branch_circ_rules
> -                                        WHERE branchcode = ?");
> -        $sth_delete->execute($branch);
> -    } else {
> -        my $sth_delete = $dbh->prepare("DELETE FROM
> branch_borrower_circ_rules
> -                                        WHERE branchcode = ?
> -                                        AND categorycode = ?");
> -        $sth_delete->execute($branch, $categorycode);
> -    }
> -}
> -elsif ($op eq 'delete-branch-item') {
> -    my $itemtype  = $input->param('itemtype');
> -    if ($branch eq "*") {
> -        if ($itemtype eq "*") {
> -            my $sth_delete = $dbh->prepare("DELETE FROM
> default_circ_rules");
> -            $sth_delete->execute();
> -        } else {
> -            my $sth_delete = $dbh->prepare("DELETE FROM
> default_branch_item_rules
> -                                            WHERE itemtype = ?");
> -            $sth_delete->execute($itemtype);
> -        }
> -    } elsif ($itemtype eq "*") {
> -        my $sth_delete = $dbh->prepare("DELETE FROM
> default_branch_circ_rules
> -                                        WHERE branchcode = ?");
> -        $sth_delete->execute($branch);
> -    } else {
> -        my $sth_delete = $dbh->prepare("DELETE FROM branch_item_rules
> -                                        WHERE branchcode = ?
> -                                        AND itemtype = ?");
> -        $sth_delete->execute($branch, $itemtype);
> -    }
> -}
> -# save the values entered
> -elsif ($op eq 'add') {
> -    my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM
> issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?");
> -    my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode,
> categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed,
> issuelength, fine, finedays, firstremind, chargeperiod,rentaldiscount)
> VALUES(?,?,?,?,?,?,?,?,?,?,?,?)");
> -    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?,
> finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?,
> reservesallowed=?, issuelength=?, rentaldiscount=?  WHERE branchcode=? AND
> categorycode=? AND itemtype=?");
> -
> -    my $br = $branch; # branch
> -    my $bor  = $input->param('categorycode'); # borrower category
> -    my $cat  = $input->param('itemtype');     # item type
> -    my $fine = $input->param('fine');
> -    my $finedays     = $input->param('finedays');
> -    my $firstremind  = $input->param('firstremind');
> -    my $chargeperiod = $input->param('chargeperiod');
> -    my $maxissueqty  = $input->param('maxissueqty');
> -    my $renewalsallowed  = $input->param('renewalsallowed');
> -    my $reservesallowed  = $input->param('reservesallowed');
> -    $maxissueqty =~ s/\s//g;
> -    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
> -    my $issuelength  = $input->param('issuelength');
> -    my $rentaldiscount = $input->param('rentaldiscount');
> -    $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
> -
> -    $sth_search->execute($br,$bor,$cat);
> -    my $res = $sth_search->fetchrow_hashref();
> -    if ($res->{total}) {
> -        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod,
> $maxissueqty, $renewalsallowed,$reservesallowed,
> $issuelength,$rentaldiscount, $br,$bor,$cat);
> -    } else {
> -
>  $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
> -    }
> -}
> -elsif ($op eq "set-branch-defaults") {
> -    my $categorycode  = $input->param('categorycode');
> -    my $maxissueqty   = $input->param('maxissueqty');
> -    my $holdallowed   = $input->param('holdallowed');
> -    $maxissueqty =~ s/\s//g;
> -    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
> -    $holdallowed =~ s/\s//g;
> -    $holdallowed = undef if $holdallowed !~ /^\d+/;
> -
> -    if ($branch eq "*") {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM default_circ_rules");
> -        my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
> -                                        (maxissueqty, holdallowed)
> -                                        VALUES (?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE default_circ_rules
> -                                        SET maxissueqty = ?, holdallowed =
> ?");
> -
> -        $sth_search->execute();
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($maxissueqty, $holdallowed);
> -        } else {
> -            $sth_insert->execute($maxissueqty, $holdallowed);
> -        }
> -    } else {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM default_branch_circ_rules
> -                                        WHERE branchcode = ?");
> -        my $sth_insert = $dbh->prepare("INSERT INTO
> default_branch_circ_rules
> -                                        (branchcode, maxissueqty,
> holdallowed)
> -                                        VALUES (?, ?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
> -                                        SET maxissueqty = ?, holdallowed =
> ?
> -                                        WHERE branchcode = ?");
> -        $sth_search->execute($branch);
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($maxissueqty, $holdallowed, $branch);
> -        } else {
> -            $sth_insert->execute($branch, $maxissueqty, $holdallowed);
> -        }
> -    }
> -}
> -elsif ($op eq "add-branch-cat") {
> -    my $categorycode  = $input->param('categorycode');
> -    my $maxissueqty   = $input->param('maxissueqty');
> -    $maxissueqty =~ s/\s//g;
> -    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
> -
> -    if ($branch eq "*") {
> -        if ($categorycode eq "*") {
> -            my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                            FROM default_circ_rules");
> -            my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
> -                                            (maxissueqty)
> -                                            VALUES (?)");
> -            my $sth_update = $dbh->prepare("UPDATE default_circ_rules
> -                                            SET maxissueqty = ?");
> -
> -            $sth_search->execute();
> -            my $res = $sth_search->fetchrow_hashref();
> -            if ($res->{total}) {
> -                $sth_update->execute($maxissueqty);
> -            } else {
> -                $sth_insert->execute($maxissueqty);
> -            }
> -        } else {
> -            my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                            FROM
> default_borrower_circ_rules
> -                                            WHERE categorycode = ?");
> -            my $sth_insert = $dbh->prepare("INSERT INTO
> default_borrower_circ_rules
> -                                            (categorycode, maxissueqty)
> -                                            VALUES (?, ?)");
> -            my $sth_update = $dbh->prepare("UPDATE
> default_borrower_circ_rules
> -                                            SET maxissueqty = ?
> -                                            WHERE categorycode = ?");
> -            $sth_search->execute($branch);
> -            my $res = $sth_search->fetchrow_hashref();
> -            if ($res->{total}) {
> -                $sth_update->execute($maxissueqty, $categorycode);
> -            } else {
> -                $sth_insert->execute($categorycode, $maxissueqty);
> -            }
> -        }
> -    } elsif ($categorycode eq "*") {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM default_branch_circ_rules
> -                                        WHERE branchcode = ?");
> -        my $sth_insert = $dbh->prepare("INSERT INTO
> default_branch_circ_rules
> -                                        (branchcode, maxissueqty)
> -                                        VALUES (?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
> -                                        SET maxissueqty = ?
> -                                        WHERE branchcode = ?");
> -        $sth_search->execute($branch);
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($maxissueqty, $branch);
> -        } else {
> -            $sth_insert->execute($branch, $maxissueqty);
> -        }
> -    } else {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM branch_borrower_circ_rules
> -                                        WHERE branchcode = ?
> -                                        AND   categorycode = ?");
> -        my $sth_insert = $dbh->prepare("INSERT INTO
> branch_borrower_circ_rules
> -                                        (branchcode, categorycode,
> maxissueqty)
> -                                        VALUES (?, ?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE branch_borrower_circ_rules
> -                                        SET maxissueqty = ?
> -                                        WHERE branchcode = ?
> -                                        AND categorycode = ?");
> -
> -        $sth_search->execute($branch, $categorycode);
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($maxissueqty, $branch, $categorycode);
> -        } else {
> -            $sth_insert->execute($branch, $categorycode, $maxissueqty);
> -        }
> -    }
> -}
> -elsif ($op eq "add-branch-item") {
> -    my $itemtype  = $input->param('itemtype');
> -    my $holdallowed   = $input->param('holdallowed');
> -    $holdallowed =~ s/\s//g;
> -    $holdallowed = undef if $holdallowed !~ /^\d+/;
> -
> -    if ($branch eq "*") {
> -        if ($itemtype eq "*") {
> -            my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                            FROM default_circ_rules");
> -            my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
> -                                            (holdallowed)
> -                                            VALUES (?)");
> -            my $sth_update = $dbh->prepare("UPDATE default_circ_rules
> -                                            SET holdallowed = ?");
> -
> -            $sth_search->execute();
> -            my $res = $sth_search->fetchrow_hashref();
> -            if ($res->{total}) {
> -                $sth_update->execute($holdallowed);
> -            } else {
> -                $sth_insert->execute($holdallowed);
> -            }
> -        } else {
> -            my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                            FROM default_branch_item_rules
> -                                            WHERE itemtype = ?");
> -            my $sth_insert = $dbh->prepare("INSERT INTO
> default_branch_item_rules
> -                                            (itemtype, holdallowed)
> -                                            VALUES (?, ?)");
> -            my $sth_update = $dbh->prepare("UPDATE
> default_branch_item_rules
> -                                            SET holdallowed = ?
> -                                            WHERE itemtype = ?");
> -            $sth_search->execute($itemtype);
> -            my $res = $sth_search->fetchrow_hashref();
> -            if ($res->{total}) {
> -                $sth_update->execute($holdallowed, $itemtype);
> -            } else {
> -                $sth_insert->execute($itemtype, $holdallowed);
> -            }
> -        }
> -    } elsif ($itemtype eq "*") {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM default_branch_circ_rules
> -                                        WHERE branchcode = ?");
> -        my $sth_insert = $dbh->prepare("INSERT INTO
> default_branch_circ_rules
> -                                        (branchcode, holdallowed)
> -                                        VALUES (?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
> -                                        SET holdallowed = ?
> -                                        WHERE branchcode = ?");
> -        $sth_search->execute($branch);
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($holdallowed, $branch);
> -        } else {
> -            $sth_insert->execute($branch, $holdallowed);
> -        }
> -    } else {
> -        my $sth_search = $dbh->prepare("SELECT count(*) AS total
> -                                        FROM branch_item_rules
> -                                        WHERE branchcode = ?
> -                                        AND   itemtype = ?");
> -        my $sth_insert = $dbh->prepare("INSERT INTO branch_item_rules
> -                                        (branchcode, itemtype,
> holdallowed)
> -                                        VALUES (?, ?, ?)");
> -        my $sth_update = $dbh->prepare("UPDATE branch_item_rules
> -                                        SET holdallowed = ?
> -                                        WHERE branchcode = ?
> -                                        AND itemtype = ?");
> -
> -        $sth_search->execute($branch, $itemtype);
> -        my $res = $sth_search->fetchrow_hashref();
> -        if ($res->{total}) {
> -            $sth_update->execute($holdallowed, $branch, $itemtype);
> -        } else {
> -            $sth_insert->execute($branch, $itemtype, $holdallowed);
> -        }
> -    }
> -}
> -
> +my ($template, $loggedinuser, $cookie) = get_template_and_user({
> +    template_name   => "admin/smart-rules.tmpl",
> +    query           => $input,
> +    type            => "intranet",
> +    authnotrequired => 0,
> +    flagsrequired   => {parameters => 1},
> +    debug           => 1,
> +});
> +
> +my $type       = $input->param('type');
> +my $branchcode = $input->param('branchcode') || ( C4::Branch::onlymine() ?
> ( C4::Branch::mybranch() || '*' ) : '*' );
> +my $op         = $input->param('op');
> +my $confirm    = $input->param('confirm');
> +
> +# This block builds the branch list
>  my $branches = GetBranches();
>  my @branchloop;
> -for my $thisbranch (sort { $branches->{$a}->{branchname} cmp
> $branches->{$b}->{branchname} } keys %$branches) {
> -    my $selected = 1 if $thisbranch eq $branch;
> +for my $thisbranch (sort { $branches->{$a}->{'branchname'} cmp
> $branches->{$b}->{'branchname'} } keys %$branches) {
> +    my $selected = 1 if $thisbranch eq $branchcode;
>     my %row =(value => $thisbranch,
>                 selected => $selected,
>                 branchname => $branches->{$thisbranch}->{'branchname'},
> @@ -343,177 +58,111 @@ for my $thisbranch (sort {
> $branches->{$a}->{branchname} cmp $branches->{$b}->{b
>     push @branchloop, \%row;
>  }
>
> -my $sth=$dbh->prepare("SELECT description,categorycode FROM categories
> ORDER BY description");
> -$sth->execute;
> -my @category_loop;
> -while (my $data=$sth->fetchrow_hashref){
> -    push @category_loop,$data;
> -}
> -
> -$sth->finish;
> -$sth=$dbh->prepare("SELECT description,itemtype FROM itemtypes ORDER BY
> description");
> -$sth->execute;
> -# $i=0;
> -my @row_loop;
> -my @itemtypes;
> -while (my $row=$sth->fetchrow_hashref){
> -    push @itemtypes,$row;
> -}
> -
> -my $sth2 = $dbh->prepare("
> -    SELECT issuingrules.*, itemtypes.description AS humanitemtype,
> categories.description AS humancategorycode
> -    FROM issuingrules
> -    LEFT JOIN itemtypes
> -        ON (itemtypes.itemtype = issuingrules.itemtype)
> -    LEFT JOIN categories
> -        ON (categories.categorycode = issuingrules.categorycode)
> -    WHERE issuingrules.branchcode = ?
> -");
> -$sth2->execute($branch);
> -
> -while (my $row = $sth2->fetchrow_hashref) {
> -    $row->{'humanitemtype'} ||= $row->{'itemtype'};
> -    $row->{'default_humanitemtype'} = 1 if $row->{'humanitemtype'} eq '*';
> -    $row->{'humancategorycode'} ||= $row->{'categorycode'};
> -    $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'}
> eq '*';
> -    $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
> -    push @row_loop, $row;
> -}
> -$sth->finish;
> +# Get the patron category list
> +my @category_loop = C4::Category->all;
>
> -my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
> +# Get the item types list
> +my @itemtypes = C4::ItemType->all;
>
> -my $sth_branch_cat;
> -if ($branch eq "*") {
> -    $sth_branch_cat = $dbh->prepare("
> -        SELECT default_borrower_circ_rules.*, categories.description AS
> humancategorycode
> -        FROM default_borrower_circ_rules
> -        JOIN categories USING (categorycode)
> -
> -    ");
> -    $sth_branch_cat->execute();
> -} else {
> -    $sth_branch_cat = $dbh->prepare("
> -        SELECT branch_borrower_circ_rules.*, categories.description AS
> humancategorycode
> -        FROM branch_borrower_circ_rules
> -        JOIN categories USING (categorycode)
> -        WHERE branch_borrower_circ_rules.branchcode = ?
> -    ");
> -    $sth_branch_cat->execute($branch);
> +if ( $op eq 'delete' ) {
> +    DelIssuingRule({
> +        branchcode   => $branchcode,
> +        categorycode => $input->param('categorycode'),
> +        itemtype     => $input->param('itemtype'),
> +    });
>  }
> +# save the values entered
> +elsif ( $op eq 'add' ) {
>
> -my @branch_cat_rules = ();
> -while (my $row = $sth_branch_cat->fetchrow_hashref) {
> -    push @branch_cat_rules, $row;
> -}
> -my @sorted_branch_cat_rules = sort { $a->{'humancategorycode'} cmp
> $b->{'humancategorycode'} } @branch_cat_rules;
> +    # Converts '' to undef, so we can have NULL in database fields
> +    my $issuingrule;
> +    for ( $input->param ) {
> +        my $v = $input->param($_);
> +        $issuingrule->{$_} = length $v ? $v : undef;
> +    }
>
> -# note undef maxissueqty so that template can deal with them
> -foreach my $entry (@sorted_branch_cat_rules, @sorted_row_loop) {
> -    $entry->{unlimited_maxissueqty} = 1 unless
> defined($entry->{maxissueqty});
> +    # We don't want op to be passed to the API
> +    delete $issuingrule->{'op'};
> +
> +    # If the (branchcode,categorycode,itemtype) combination already
> exists...
> +    my @issuingrules = GetIssuingRules({
> +        branchcode      => $issuingrule->{'branchcode'},
> +        categorycode    => $issuingrule->{'categorycode'},
> +        itemtype        => $issuingrule->{'itemtype'},
> +    });
> +
> +    # ...we modify the existing rule...
> +    if ( @issuingrules ) {
> +        ModIssuingRule( $issuingrule );
> +#    } elsif (@issuingrules){
> +#        $template->param(confirm=>1);
> +#        $template->param(%$issuingrule);
> +#        foreach (@category_loop) {
> +#            $_->{selected}="selected" if ($_->{categorycode} eq
> $issuingrule->{categorycode});
> +#        }
> +#        foreach (@itemtypes) {
> +#            $_->{selected}="selected" if ($_->{itemtype} eq
> $issuingrule->{itemtype});
> +#        }
> +    # ...else we add a new rule.
> +    } else {
> +        AddIssuingRule( $issuingrule );
> +    }
>  }
>
> -my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
> -
> -my $sth_branch_item;
> -if ($branch eq "*") {
> -    $sth_branch_item = $dbh->prepare("
> -        SELECT default_branch_item_rules.*, itemtypes.description AS
> humanitemtype
> -        FROM default_branch_item_rules
> -        JOIN itemtypes USING (itemtype)
> -    ");
> -    $sth_branch_item->execute();
> -} else {
> -    $sth_branch_item = $dbh->prepare("
> -        SELECT branch_item_rules.*, itemtypes.description AS humanitemtype
> -        FROM branch_item_rules
> -        JOIN itemtypes USING (itemtype)
> -        WHERE branch_item_rules.branchcode = ?
> -    ");
> -    $sth_branch_item->execute($branch);
> -}
> +# Get the issuing rules list...
> +my @issuingrules = GetIssuingRulesByBranchCode($branchcode);
>
> -my @branch_item_rules = ();
> -while (my $row = $sth_branch_item->fetchrow_hashref) {
> -    push @branch_item_rules, $row;
> -}
> -my @sorted_branch_item_rules = sort { $a->{'humanitemtype'} cmp
> $b->{'humanitemtype'} } @branch_item_rules;
> +# ...and refine its data, row by row.
> +for my $rule ( @issuingrules ) {
> +    $rule->{'humanitemtype'}             ||= $rule->{'itemtype'};
> +    $rule->{'default_humanitemtype'}       = $rule->{'humanitemtype'} eq
> '*';
> +    $rule->{'humancategorycode'}         ||= $rule->{'categorycode'};
> +    $rule->{'default_humancategorycode'}   = $rule->{'humancategorycode'}
> eq '*';
>
> -# note undef holdallowed so that template can deal with them
> -foreach my $entry (@sorted_branch_item_rules) {
> -    $entry->{holdallowed_any} = 1 if($entry->{holdallowed} == 2);
> -    $entry->{holdallowed_same} = 1 if($entry->{holdallowed} == 1);
> +    # This block is to show herited values in grey.
> +    # We juste compare keys from our raw rule, with keys from the computed
> rule.
> +    my $computedrule = GetIssuingRule($rule->{'categorycode'},
> $rule->{'itemtype'}, $rule->{'branchcode'});
> +    for ( keys %$rule ) {
> +        if ( not defined $rule->{$_} ) {
> +            $rule->{$_} = $computedrule->{$_};
> +            $rule->{"herited_$_"} = 1;
> +        }
> +    }
>  }
>
> -$template->param(show_branch_cat_rule_form => 1);
> -$template->param(branch_item_rule_loop => \@sorted_branch_item_rules);
> -$template->param(branch_cat_rule_loop => \@sorted_branch_cat_rules);
> +# Get the issuing rules list...
> +my @issuingrules = GetIssuingRulesByBranchCode($branchcode);
>
> -my $sth_defaults;
> -if ($branch eq "*") {
> -    $sth_defaults = $dbh->prepare("
> -        SELECT *
> -        FROM default_circ_rules
> -    ");
> -    $sth_defaults->execute();
> -} else {
> -    $sth_defaults = $dbh->prepare("
> -        SELECT *
> -        FROM default_branch_circ_rules
> -        WHERE branchcode = ?
> -    ");
> -    $sth_defaults->execute($branch);
> -}
> +# ...and refine its data, row by row.
> +for my $rule ( @issuingrules ) {
> +    $rule->{'humanitemtype'}             ||= $rule->{'itemtype'};
> +    $rule->{'default_humanitemtype'}       = $rule->{'humanitemtype'} eq
> '*';
> +    $rule->{'humancategorycode'}         ||= $rule->{'categorycode'};
> +    $rule->{'default_humancategorycode'}   = $rule->{'humancategorycode'}
> eq '*';
>
> -my $defaults = $sth_defaults->fetchrow_hashref;
> +    # This block is to show herited values in grey.
> +    # We juste compare keys from our raw rule, with keys from the computed
> rule.
> +    my $computedrule = GetIssuingRule($rule->{'categorycode'},
> $rule->{'itemtype'}, $rule->{'branchcode'});
> +    for ( keys %$rule ) {
> +        if ( not defined $rule->{$_} ) {
> +            $rule->{$_} = $computedrule->{$_};
> +            $rule->{"herited_$_"} = 1;
> +        }
> +    }
>
> -if ($defaults) {
> -    $template->param(default_holdallowed_none => 1)
> if($defaults->{holdallowed} == 0);
> -    $template->param(default_holdallowed_same => 1)
> if($defaults->{holdallowed} == 1);
> -    $template->param(default_holdallowed_any => 1)
> if($defaults->{holdallowed} == 2);
> -    $template->param(default_maxissueqty => $defaults->{maxissueqty});
> +    $rule->{'fine'}                        = sprintf('%.2f',
> $rule->{'fine'});
>  }
>
> -$template->param(default_rules => ($defaults ? 1 : 0));
> -
> -$template->param(categoryloop => \@category_loop,
> -                        itemtypeloop => \@itemtypes,
> -                        rules => \@sorted_row_loop,
> -                        branchloop => \@branchloop,
> -                        humanbranch => ($branch ne '*' ?
> $branches->{$branch}->{branchname} : ''),
> -                        branch => $branch,
> -                        definedbranch => scalar(@sorted_row_loop)>0
> -                        );
> +$template->param(
> +    categoryloop  => \@category_loop,
> +    itemtypeloop  => \@itemtypes,
> +    rules         => \@issuingrules,
> +    branchloop    => \@branchloop,
> +    humanbranch   => ($branchcode ne '*' ?
> $branches->{$branchcode}->{branchname} : ''),
> +    branchcode    => $branchcode,
> +    definedbranch => scalar(@issuingrules) > 0,
> +);
>  output_html_with_http_headers $input, $cookie, $template->output;
>
>  exit 0;
>
> -# sort by patron category, then item type, putting
> -# default entries at the bottom
> -sub by_category_and_itemtype {
> -    unless (by_category($a, $b)) {
> -        return by_itemtype($a, $b);
> -    }
> -}
> -
> -sub by_category {
> -    my ($a, $b) = @_;
> -    if ($a->{'default_humancategorycode'}) {
> -        return ($b->{'default_humancategorycode'} ? 0 : 1);
> -    } elsif ($b->{'default_humancategorycode'}) {
> -        return -1;
> -    } else {
> -        return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
> -    }
> -}
> -
> -sub by_itemtype {
> -    my ($a, $b) = @_;
> -    if ($a->{'default_humanitemtype'}) {
> -        return ($b->{'default_humanitemtype'} ? 0 : 1);
> -    } elsif ($b->{'default_humanitemtype'}) {
> -        return -1;
> -    } else {
> -        return $a->{'humanitemtype'} cmp $b->{'humanitemtype'};
> -    }
> -}
> diff --git a/circ/branchtransfers.pl b/circ/branchtransfers.pl
> index ab38749..6374f71 100755
> --- a/circ/branchtransfers.pl
> +++ b/circ/branchtransfers.pl
> @@ -87,7 +87,9 @@ if ( $request eq "KillWaiting" ) {
>  }
>  elsif ( $request eq "SetWaiting" ) {
>     my $item = $query->param('itemnumber');
> -    ModReserveAffect( $item, $borrowernumber );
> +    my $itemhash=C4::Items::GetItem($item);
> +    my ( $reservetype, $reserve ) = C4::Reserves::CheckReserves( undef,
> $itemhash->{barcode} );
> +    ModReserveAffect( $item, $borrowernumber,$tobranchcd ne
> C4::Context->userenv->{'branch'}, $reserve->{reservenumber});
>     $ignoreRs    = 1;
>     $setwaiting  = 1;
>     $reqmessage  = 1;
> diff --git a/circ/circulation.pl b/circ/circulation.pl
> index c4421ed..a7c8716 100755
> --- a/circ/circulation.pl
> +++ b/circ/circulation.pl
> @@ -30,27 +30,33 @@ use C4::Dates qw/format_date/;
>  use C4::Branch; # GetBranches
>  use C4::Koha;   # GetPrinter
>  use C4::Circulation;
> +use C4::Overdues qw/CheckBorrowerDebarred/;
>  use C4::Members;
>  use C4::Biblio;
>  use C4::Reserves;
>  use C4::Context;
> +use C4::Debug;
>  use CGI::Session;
> -
> +use C4::Items;
> +use JSON;
> +use YAML;
>  use Date::Calc qw(
>   Today
>   Add_Delta_YM
>   Add_Delta_Days
>   Date_to_Days
>  );
> +use List::MoreUtils qw/uniq/;
>
>
>  #
>  # PARAMETERS READING
>  #
>  my $query = new CGI;
> -
> -my $sessionID = $query->cookie("CGISESSID") ;
> -my $session = get_session($sessionID);
> +my $dbh = C4::Context->dbh;
> +my $remotehost = $query->remote_host();
> +my $sessionID  = $query->cookie("CGISESSID");
> +my $session    = get_session($sessionID);
>
>  # branch and printer are now defined by the userenv
>  # but first we have to check if someone has tried to change them
> @@ -88,9 +94,14 @@ my ( $template, $loggedinuser, $cookie ) =
> get_template_and_user (
>
>  my $branches = GetBranches();
>
> -my @failedrenews = $query->param('failedrenew');    # expected to be
> itemnumbers
> +my @failedrenews  = $query->param('failedrenew');   # expected to be
> itemnumbers
> +my @failedreturns = $query->param('failedreturn');  # expected to be
> barcodes
> +my @renewerrors   = $query->param('renewerror');    # expected to be json
> +my @returnerrors  = $query->param('returnerror');   # expected to be json
>  my %renew_failed;
> -for (@failedrenews) { $renew_failed{$_} = 1; }
> +my %return_failed;
> +for (@failedrenews) { $renew_failed{$_} = decode_json(shift @renewerrors);
> }
> +for (@failedreturns) { $return_failed{GetItemnumberFromBarcode($_)} =
> decode_json(shift @returnerrors); }
>
>  my $findborrower = $query->param('findborrower');
>  $findborrower =~ s|,| |g;
> @@ -125,14 +136,13 @@ my $organisation   = $query->param('organisations');
>  my $print          = $query->param('print');
>  my $newexpiry      = $query->param('dateexpiry');
>  my $debt_confirmed = $query->param('debt_confirmed') || 0; # Don't show
> the debt error dialog twice
> -
> +$debug && warn $newexpiry;
>  # Check if stickyduedate is turned off
>  if ( $barcode ) {
>     # was stickyduedate loaded from session?
>     if ( $stickyduedate && ! $query->param("stickyduedate") ) {
>         $session->clear( 'stickyduedate' );
>         $stickyduedate  = $query->param('stickyduedate');
> -        $duedatespec    = $query->param('duedatespec');
>     }
>  }
>
> @@ -169,7 +179,7 @@ if($duedatespec_allow){
>     $datedue = $globalduedate if ($globalduedate);
>  }
>
> -my $todaysdate = C4::Dates->new->output('iso');
> +my $todaysdate = C4::Dates->new->output( 'iso' );
>
>  # check and see if we should print
>  if ( $barcode eq '' && $print eq 'maybe' ) {
> @@ -231,8 +241,8 @@ if ($borrowernumber) {
>
>     # Warningdate is the date that the warning starts appearing
>     my (  $today_year,   $today_month,   $today_day) = Today();
> -    my ($warning_year, $warning_month, $warning_day) = split /-/,
> $borrower->{'dateexpiry'};
> -    my (  $enrol_year,   $enrol_month,   $enrol_day) = split /-/,
> $borrower->{'dateenrolled'};
> +    my ($warning_year, $warning_month, $warning_day) = split (/-/,
> $borrower->{'dateexpiry'});
> +    my (  $enrol_year,   $enrol_month,   $enrol_day) = split (/-/,
> $borrower->{'dateenrolled'});
>     # Renew day is calculated by adding the enrolment period to today
>     my (  $renew_year,   $renew_month,   $renew_day);
>     if ($enrol_year*$enrol_month*$enrol_day>0) {
> @@ -250,6 +260,7 @@ if ($borrowernumber) {
>             flagged  => "1",
>             noissues => "1",
>             expired     => format_date($borrower->{dateexpiry}),
> +            warning     => 1,
>             renewaldate =>
> format_date("$renew_year-$renew_month-$renew_day")
>         );
>     }
> @@ -260,9 +271,9 @@ if ($borrowernumber) {
>     {
>         # borrower card soon to expire warn librarian
>         $template->param("warndeparture" =>
> format_date($borrower->{dateexpiry}),
> -        flagged       => "1",);
> +        flagged       => "1", "warning" => 1);
>         if (C4::Context->preference('ReturnBeforeExpiry')){
> -            $template->param("returnbeforeexpiry" => 1);
> +            $template->param("returnbeforeexpiry" => 1, "warning => 1");
>         }
>     }
>     $template->param(
> @@ -270,12 +281,22 @@ if ($borrowernumber) {
>         issuecount   => $issue,
>         finetotal    => $fines
>     );
> +
> +    my $debar = CheckBorrowerDebarred($borrowernumber);
> +    if($debar){
> +        $template->param(userdebarred => 1);
> +        $template->param(debarredcomment => $borrower->{debarredcomment});
> +        if( $debar ne "9999-12-31"){
> +            $template->param(userdebarreddate =>
> C4::Dates::format_date($debar));
> +        }
> +    }
>  }
>
>  #
>  # STEP 3 : ISSUING
>  #
>  #
> +my $confirm_required = 0;
>  if ($barcode) {
>     # always check for blockers on issuing
>     my ( $error, $question ) =
> @@ -320,8 +341,33 @@ if ($barcode) {
>     # FIXME If the issue is confirmed, we launch another time
> GetMemberIssuesAndFines, now display the issue count after issue
>     my ( $od, $issue, $fines ) = GetMemberIssuesAndFines( $borrowernumber
> );
>     $template->param( issuecount   => $issue );
> +
> +    # Is there a circulation note?
> +    my $itemnumber = GetItemnumberFromBarcode($barcode);
> +    my $biblionumber = GetBiblionumberFromItemnumber($itemnumber);
> +    my $record = GetMarcBiblio($biblionumber);
> +    my $frameworkcode = GetFrameworkCode($biblionumber);
> +    my $circnotefield = GetRecordValue('circnote', $record,
> $frameworkcode);
> +    if (defined @$circnotefield[0]) {
> +       $template->param(circnote => @$circnotefield[0]->{'subfield'});
> +    }
>  }
>
> +
> +# Setting the right status if an hold has been confirmed
> +#This should never be used in fact
> +my $resbarcode = $query->param("resbarcode");
> +if ($resbarcode) {
> +        if ( my ( $reservetype, $reserve ) = C4::Reserves::CheckReserves(
> undef, $resbarcode ) ) {
> +            if ( $reservetype eq "Waiting" || $reservetype eq "Reserved" )
> {
> +                my $transfer = C4::Context->userenv->{branch} ne
> $reserve->{branchcode};
> +                ModReserveAffect( $reserve->{itemnumber},
> $reserve->{borrowernumber}, $transfer, $reserve->{"reservenumber"} );
> +            }
> +        }
> +}
> +
> +
> +
>  # reload the borrower info for the sake of reseting the flags.....
>  if ($borrowernumber) {
>     $borrower = GetMemberDetails( $borrowernumber, 0 );
> @@ -359,11 +405,18 @@ if ($borrowernumber) {
>         $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
>         $getreserv{biblionumber}   = $getiteminfo->{'biblionumber'};
>         $getreserv{waitingat}      = GetBranchName(
> $num_res->{'branchcode'} );
> +       my $materials = $getiteminfo->{'materials'};
> +        $template->param(materials         => $materials);
>         #         check if we have a waiting status for reservations
>         if ( $num_res->{'found'} eq 'W' ) {
>             $getreserv{color}   = 'reserved';
>             $getreserv{waiting} = 1;
>  #     genarate information displaying only waiting reserves
> +        my @maxpickupdate = $num_res->{'waitingdate'} ? GetMaxPickupDate(
> $num_res->{'waitingdate'}, $borrowernumber, $num_res ) : '';
> +        $getreserv{'maxpickupdate'} = sprintf( "%d-%02d-%02d",
> @maxpickupdate );
> +        $getWaitingReserveInfo{'formattedwaitingdate'} = format_date(
> $getreserv{'maxpickupdate'} );
> +        $getreserv{'formattedwaitingdate'} = format_date(
> $getreserv{'maxpickupdate'} );
> +
>         $getWaitingReserveInfo{title}        = $getiteminfo->{'title'};
>         $getWaitingReserveInfo{biblionumber} =
> $getiteminfo->{'biblionumber'};
>         $getWaitingReserveInfo{itemtype}     =
> $itemtypeinfo->{'description'};
> @@ -419,51 +472,97 @@ my $previssues   = '';
>  my @todaysissues;
>  my @previousissues;
>
> +my @borrowers_with_issues;
> +my @relissues;
> +my @relprevissues;
> +my $displayrelissues;
> +## ADDED BY JF: new itemtype issuingrules counter stuff
> +my $issued_itemtypes_count;
> +my @issued_itemtypes_count_loop;
> +
>  my $totalprice = 0;
>
> -if ($borrower) {
> -# get each issue of the borrower & separate them in todayissues & previous
> issues
> -    my ($issueslist) = GetPendingIssues($borrower->{'borrowernumber'});
> -    # split in 2 arrays for today & previous
> -    foreach my $it ( @$issueslist ) {
> -        my $itemtypeinfo = getitemtypeinfo(
> (C4::Context->preference('item-level_itypes')) ? $it->{'itype'} :
> $it->{'itemtype'} );
> -        # set itemtype per item-level_itype syspref - FIXME this is an
> ugly hack
> -        $it->{'itemtype'} = ( C4::Context->preference( 'item-level_itypes'
> ) ) ? $it->{'itype'} : $it->{'itemtype'};
> +sub build_issue_data {
> +    my $issueslist = shift;
> +    my $relatives = shift;
>
> -        ($it->{'charge'}, $it->{'itemtype_charge'}) = GetIssuingCharges(
> -            $it->{'itemnumber'}, $borrower->{'borrowernumber'}
> -        );
> -        $it->{'charge'} = sprintf("%.2f", $it->{'charge'});
> -        my ($can_renew, $can_renew_error) = CanBookBeRenewed(
> -            $borrower->{'borrowernumber'},$it->{'itemnumber'}
> -        );
> -        $it->{"renew_error_${can_renew_error}"} = 1 if defined
> $can_renew_error;
> +  # split in 2 arrays for today & previous
> +    foreach my $it (@$issueslist) {
> +        my $itemtypeinfo = getitemtypeinfo( (
> C4::Context->preference('item-level_itypes') ) ? $it->{'itype'} :
> $it->{'itemtype'} );
> +
> +       # Getting borrower details
> +       my $memberdetails = GetMemberDetails($it->{'borrowernumber'});
> +       $it->{'borrowername'} = $memberdetails->{'firstname'} . " " .
> $memberdetails->{'surname'};
> +
> +        # set itemtype per item-level_itype syspref - FIXME this is an
> ugly hack
> +        $it->{'itemtype'} = ( C4::Context->preference('item-level_itypes')
> ) ? $it->{'itype'} : $it->{'itemtype'};
> +
> +        ( $it->{'charge'}, $it->{'itemtype_charge'} ) = GetIssuingCharges(
> $it->{'itemnumber'}, $borrower->{'borrowernumber'} );
> +        $it->{'charge'} = sprintf( "%.2f", $it->{'charge'} );
> +        my ( $can_renew, $can_renew_error ) = CanBookBeRenewed(
> $borrower->{'borrowernumber'}, $it->{'itemnumber'} );
> +        if ( defined $can_renew_error->{message} ) {
> +            $it->{ "renew_error_" . $can_renew_error->{message} } = 1;
> +            $it->{'renew_error'} = 1;
> +        }
> +        $it->{renewals} ||= 0;
> +        $it->{$_} = $can_renew_error->{$_} for (qw(renewalsallowed
> reserves));
>         my ( $restype, $reserves ) = CheckReserves( $it->{'itemnumber'} );
> -        $it->{'can_renew'} = $can_renew;
> -        $it->{'can_confirm'} = !$can_renew && !$restype;
> -        $it->{'renew_error'} = $restype;
> -        $it->{'checkoutdate'} =
> C4::Dates->new($it->{'issuedate'},'iso')->output('syspref');
> +        if ($restype) {
> +            $it->{'reserved'} = 1;
> +            $it->{$restype} = 1;
> +        }
> +        $it->{'can_renew'}    = $can_renew;
> +        $it->{'can_confirm'}  = !$can_renew && !$restype;
> +        $it->{'renew_error'}  = $restype;
> +        $it->{'checkoutdate'} = $it->{'issuedate'};
>
>         $totalprice += $it->{'replacementprice'};
> -        $it->{'itemtype'} = $itemtypeinfo->{'description'};
> +        $it->{'itemtype'}       = $itemtypeinfo->{'description'};
>         $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
> -        $it->{'dd'} = format_date($it->{'date_due'});
> -        $it->{'displaydate'} = format_date($it->{'issuedate'});
> -        $it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
> -        ($it->{'author'} eq '') and $it->{'author'} = ' ';
> -        $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}};
> -
> -        if ( $todaysdate eq $it->{'issuedate'} or $todaysdate eq
> $it->{'lastreneweddate'} ) {
> -            push @todaysissues, $it;
> -        } else {
> -            push @previousissues, $it;
> +        $it->{'dd'}             = format_date( $it->{'date_due'} );
> +        $it->{'displaydate'}    = format_date( $it->{'issuedate'} );
> +        ( $it->{'author'} eq '' ) and $it->{'author'} = ' ';
> +        if ( defined( $return_failed{ $it->{'itemnumber'} } ) ) {
> +            $it->{ 'return_error_' . $return_failed{ $it->{'itemnumber'}
> }->{message} } = 1;
> +            delete $return_failed{ $it->{'itemnumber'} };
>         }
> +        if ( defined( $renew_failed{ $it->{'itemnumber'} } ) ) {
> +            $it->{ 'renew_error_' . $renew_failed{ $it->{'itemnumber'}
> }->{message} } = 1;
> +        }
> +        $it->{'return_failed'} = defined( $return_failed{
> $it->{'itemnumber'} } );
> +        $it->{'branchdisplay'} = GetBranchName( (
> C4::Context->preference('HomeOrHoldingBranch') eq 'holdingbranch' ) ?
> $it->{'holdingbranch'} : $it->{'homebranch'} );
> +
> +        # ADDED BY JF: NEW ITEMTYPE COUNT DISPLAY
> +        $issued_itemtypes_count->{ $it->{'itemtype'} }++;
> +       if ( $todaysdate eq $it->{'checkoutdate'} or $todaysdate eq
> $it->{'lastreneweddate'} ) {
> +           (!$relatives) ? push @todaysissues, $it : push @relissues, $it;
> +       } else {
> +           (!$relatives) ? push @previousissues, $it : push
> @relprevissues, $it;
> +       }
> +
>     }
> -    if ( C4::Context->preference( "todaysIssuesDefaultSortOrder" ) eq
> 'asc' ) {
> -        @todaysissues   = sort { $a->{'timestamp'} cmp $b->{'timestamp'} }
> @todaysissues;
> -    }
> -    else {
> -        @todaysissues   = sort { $b->{'timestamp'} cmp $a->{'timestamp'} }
> @todaysissues;
> +
> +}
> +
> +if ($borrower) {
> +
> +    # Getting borrower relatives
> +    my @relborrowernumbers =
> GetMemberRelatives($borrower->{'borrowernumber'});
> +    #push @borrowernumbers, $borrower->{'borrowernumber'};
> +
> +    # get each issue of the borrower & separate them in todayissues &
> previous issues
> +    my ($issueslist) = GetPendingIssues($borrower->{'borrowernumber'});
> +    my ($relissueslist) = GetPendingIssues(@relborrowernumbers);
> +
> +    build_issue_data($issueslist, 0);
> +    build_issue_data($relissueslist, 1);
> +
> +    $displayrelissues = scalar($relissueslist);
> +
> +    if ( C4::Context->preference("todaysIssuesDefaultSortOrder") eq 'asc'
> ) {
> +        @todaysissues = sort { $a->{'timestamp'} cmp $b->{'timestamp'} }
> @todaysissues;
> +    } else {
> +        @todaysissues = sort { $b->{'timestamp'} cmp $a->{'timestamp'} }
> @todaysissues;
>     }
>     if ( C4::Context->preference( "previousIssuesDefaultSortOrder" ) eq
> 'asc' ){
>         @previousissues = sort { $a->{'date_due'} cmp $b->{'date_due'} }
> @previousissues;
> @@ -472,7 +571,48 @@ if ($borrower) {
>         @previousissues = sort { $b->{'date_due'} cmp $a->{'date_due'} }
> @previousissues;
>     }
>  }
> +my @reserveswaiting;
> +foreach my $itemnumber (keys %return_failed){
> +   next unless $return_failed{$itemnumber}->{'reservesdata'};
> +   my $hashdata=$return_failed{$itemnumber}->{'reservesdata'};
> +   $hashdata->{circborrowernumber}=$borrowernumber;
> +   $hashdata->{script_name}=$query->script_name();
> +   push @reserveswaiting, $hashdata if (%$hashdata);
> +}
> +
> +$template->param(reserves_waiting=>\@reserveswaiting);
> +
> +#### ADDED BY JF FOR COUNTS BY ITEMTYPE RULES
> +# FIXME: This should utilize all the issuingrules options rather than just
> the defaults
> +# and it should be moved to a module
> +
> +# how many of each is allowed?
> +my $issueqty_sth = $dbh->prepare(
> +    'SELECT itemtypes.description AS
> description,issuingrules.itemtype,maxissueqty ' .
> +    'FROM issuingrules LEFT JOIN itemtypes ON
> (itemtypes.itemtype=issuingrules.itemtype) ' .
> +    'WHERE categorycode=?'
> +);
> +$issueqty_sth->execute(q{*}); # This is a literal asterisk, not a
> wildcard.
> +
> +while ( my $data = $issueqty_sth->fetchrow_hashref() ) {
> +
> +    # subtract how many of each this borrower has
> +    $data->{'count'} = $issued_itemtypes_count->{ $data->{'description'}
> };
> +    $data->{'left'}  =
> +      ( $data->{'maxissueqty'} -
> +          $issued_itemtypes_count->{ $data->{'description'} } );
> +
> +    # can't have a negative number of remaining
> +    if ( $data->{'left'} < 0 ) { $data->{'left'} = '0' }
> +    if ( $data->{maxissueqty} <= $data->{count} ) {
> +        $data->{flag} = 1;
> +    }
> +    if ( $data->{maxissueqty} > 0 && $data->{itemtype} !~m/^(\*|CIRC)$/ )
> {
> +        push @issued_itemtypes_count_loop, $data;
> +    }
> +}
>
> +#### / JF
>
>  my @values;
>  my %labels;
> @@ -502,6 +642,7 @@ if ($borrowerslist) {
>
>  #title
>  my $flags = $borrower->{'flags'};
> +    $debug && warn Dump($flags);
>  foreach my $flag ( sort keys %$flags ) {
>     $template->param( flagged=> 1);
>     $flags->{$flag}->{'message'} =~ s#\n#<br />#g;
> @@ -511,20 +652,19 @@ foreach my $flag ( sort keys %$flags ) {
>             noissues => 'true',
>         );
>         if ( $flag eq 'GNA' ) {
> -            $template->param( gna => 'true' );
> +            $template->param( gna => 'true', gonenoaddresscomment =>
> $borrower->{'gonenoaddresscomment'}, warning => 1 );
>         }
>         elsif ( $flag eq 'LOST' ) {
> -            $template->param( lost => 'true' );
> -        }
> -        elsif ( $flag eq 'DBARRED' ) {
> -            $template->param( dbarred => 'true' );
> -        }
> -        elsif ( $flag eq 'CHARGES' ) {
> +            $template->param( lost => 'true', lostcomment =>
> $borrower->{'lostcomment'}, warning => 1 );
> +        } elsif ( $flag eq 'DEBARRED' ) {
> +            $template->param( userdebarred => 'true', warning => 1,
> userdebarreddate=>
> format_date($flags->{DEBARRED}->{dateend}),debardebarredcomment=>$borrower->{'debarredcomment'});
> +        } elsif ( $flag eq 'CHARGES' ) {
>             $template->param(
>                 charges    => 'true',
>                 chargesmsg => $flags->{'CHARGES'}->{'message'},
>                 chargesamount => $flags->{'CHARGES'}->{'amount'},
> -                charges_is_blocker => 1
> +                charges_is_blocker => 1,
> +                warning => 1
>             );
>         }
>         elsif ( $flag eq 'CREDITS' ) {
> @@ -532,6 +672,7 @@ foreach my $flag ( sort keys %$flags ) {
>                 credits    => 'true',
>                 creditsmsg => $flags->{'CREDITS'}->{'message'},
>                 creditsamount => sprintf("%.02f",
> -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
> +                       warning => 1
>             );
>         }
>     }
> @@ -542,6 +683,7 @@ foreach my $flag ( sort keys %$flags ) {
>                 flagged    => 1,
>                 chargesmsg => $flags->{'CHARGES'}->{'message'},
>                 chargesamount => $flags->{'CHARGES'}->{'amount'},
> +                warning => 1
>             );
>         }
>         elsif ( $flag eq 'CREDITS' ) {
> @@ -549,13 +691,15 @@ foreach my $flag ( sort keys %$flags ) {
>                 credits    => 'true',
>                 creditsmsg => $flags->{'CREDITS'}->{'message'},
>                 creditsamount => sprintf("%.02f",
> -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
> +               warning => 1
>             );
>         }
>         elsif ( $flag eq 'ODUES' ) {
>             $template->param(
>                 odues    => 'true',
>                 flagged  => 1,
> -                oduesmsg => $flags->{'ODUES'}->{'message'}
> +                oduesmsg => $flags->{'ODUES'}->{'message'},
> +                warning => 1
>             );
>
>             my $items = $flags->{$flag}->{'itemlist'};
> @@ -610,9 +754,16 @@ if($lib_messages_loop){ $template->param(flagged => 1
> ); }
>  my $bor_messages_loop = GetMessages( $borrowernumber, 'B', $branch );
>  if($bor_messages_loop){ $template->param(flagged => 1 ); }
>
> +
>  # Computes full borrower address
>  my (undef, $roadttype_hashref) = &GetRoadTypes();
> -my $address = $borrower->{'streetnumber'}.'
> '.$roadttype_hashref->{$borrower->{'streettype'}}.'
> '.$borrower->{'address'};
> +my $address = $borrower->{'streetnumber'}.' ' if
> ($borrower->{'streetnumber'});
> +$address    .= $roadttype_hashref->{$borrower->{'streettype'}}.' ' if (
> $roadttype_hashref->{$borrower->{'streettype'}});
> +$address    .= $borrower->{'address'};
> +
> +
> +$duedatespec = "" if not ($stickyduedate or scalar $confirm_required);
> +my @categories = C4::Category->all;
>
>  $template->param(
>     lib_messages_loop => $lib_messages_loop,
> @@ -627,9 +778,9 @@ $template->param(
>     printername       => $printer,
>     firstname         => $borrower->{'firstname'},
>     surname           => $borrower->{'surname'},
> -    dateexpiry        => format_date($newexpiry),
> +    printer                     => $printer,
> +    printername                 => $printer,
>     expiry            => format_date($borrower->{'dateexpiry'}),
> -    categorycode      => $borrower->{'categorycode'},
>     categoryname      => $borrower->{description},
>     address           => $address,
>     address2          => $borrower->{'address2'},
> @@ -640,7 +791,6 @@ $template->param(
>     zipcode           => $borrower->{'zipcode'},
>     country           => $borrower->{'country'},
>     phone             => $borrower->{'phone'} || $borrower->{'mobile'},
> -    cardnumber        => $borrower->{'cardnumber'},
>     amountold         => $amountold,
>     barcode           => $barcode,
>     stickyduedate     => $stickyduedate,
> @@ -651,14 +801,22 @@ $template->param(
>     totaldue          => sprintf('%.2f', $total),
>     todayissues       => \@todaysissues,
>     previssues        => \@previousissues,
> +    relissues                  => \@relissues,
> +    relprevissues              => \@relprevissues,
> +    displayrelissues           => $displayrelissues,
>     inprocess         => $inprocess,
>     memberofinstution => $member_of_institution,
>     CGIorganisations  => $CGIorganisations,
>     is_child          => ($borrower->{'category_type'} eq 'C'),
>     circview => 1,
>     soundon           => C4::Context->preference("SoundOn"),
> +    categoryloop                               => \@categories,
>  );
>
> +$template->param(newexpiry => format_date($newexpiry)) if (defined
> $newexpiry);
> +
> +SetMemberInfosInTemplate($borrowernumber, $template);
> +
>  # save stickyduedate to session
>  if ($stickyduedate) {
>     $session->param( 'stickyduedate', $duedatespec );
> diff --git a/circ/returns.pl b/circ/returns.pl
> index 2aac76a..13c3283 100755
> --- a/circ/returns.pl
> +++ b/circ/returns.pl
> @@ -36,16 +36,20 @@ use C4::Circulation;
>  use C4::Dates qw/format_date/;
>  use Date::Calc qw/Add_Delta_Days/;
>  use C4::Calendar;
> +use C4::Budgets qw/GetCurrency/;
>  use C4::Print;
>  use C4::Reserves;
>  use C4::Biblio;
>  use C4::Items;
>  use C4::Members;
> +use C4::Overdues qw/CheckBorrowerDebarred/;
>  use C4::Branch; # GetBranches GetBranchName
>  use C4::Koha;   # FIXME : is it still useful ?
>  use C4::RotatingCollections;
> +use C4::Debug;
>
>  my $query = new CGI;
> +my $remotehost = $query->remote_host();
>
>  if (!C4::Context->userenv){
>     my $sessionID = $query->cookie("CGISESSID");
> @@ -133,6 +137,7 @@ if ( $query->param('resbarcode') ) {
>     my $item           = $query->param('itemnumber');
>     my $borrowernumber = $query->param('borrowernumber');
>     my $resbarcode     = $query->param('resbarcode');
> +    my $reservenumber = $query->param('reservenumber');
>     my $diffBranchReturned = $query->param('diffBranch');
>     my $iteminfo   = GetBiblioFromItemNumber($item);
>     # fix up item type for display
> @@ -140,18 +145,19 @@ if ( $query->param('resbarcode') ) {
>     my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ?
> $diffBranchReturned : undef;
>  # diffBranchSend tells ModReserveAffect whether document is expected in
> this library or not,
>  # i.e., whether to apply waiting status
> -    ModReserveAffect( $item, $borrowernumber, $diffBranchSend);
> +    ModReserveAffect( $item, $borrowernumber, $diffBranchSend,
> $reservenumber );
> +
>  #   check if we have other reserves for this document, if we have a return
> send the message of transfer
> -    my ( $messages, $nextreservinfo ) = GetOtherReserves($item);
> +    my ( $reservemessages, $nextreservinfo ) = GetOtherReserves($item);
>
>     my ($borr) = GetMemberDetails( $nextreservinfo, 0 );
>     my $name   = $borr->{'surname'} . ", " . $borr->{'title'} . " " .
> $borr->{'firstname'};
> -    if ( $messages->{'transfert'} ) {
> +    if ( $reservemessages->{'transfert'} ) {
>         $template->param(
>             itemtitle      => $iteminfo->{'title'},
>             itembiblionumber => $iteminfo->{'biblionumber'},
>             iteminfo       => $iteminfo->{'author'},
> -            tobranchname   => GetBranchName($messages->{'transfert'}),
> +            tobranchname   =>
> GetBranchName($reservemessages->{'transfert'}),
>             name           => $name,
>             borrowernumber => $borrowernumber,
>             borcnum        => $borr->{'cardnumber'},
> @@ -167,10 +173,12 @@ my $returned = 0;
>  my $messages;
>  my $issueinformation;
>  my $itemnumber;
> +my $biblio;
>  my $barcode     = $query->param('barcode');
>  my $exemptfine  = $query->param('exemptfine');
>  my $dropboxmode = $query->param('dropboxmode');
>  my $dotransfer  = $query->param('dotransfer');
> +my $override    = $query->param('override');
>  my $calendar    = C4::Calendar->new( branchcode => $userenv_branch );
>  #dropbox: get last open day (today - 1)
>  my $today       = C4::Dates->new();
> @@ -184,7 +192,7 @@ if ($dotransfer){
>  }
>
>  # actually return book and prepare item table.....
> -if ($barcode) {
> +if ($barcode and not $query->param('cancel')) {
>     $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace
>     $barcode = barcodedecode($barcode) if
> C4::Context->preference('itemBarcodeInputFilter');
>     $itemnumber = GetItemnumberFromBarcode($barcode);
> @@ -207,11 +215,19 @@ if ($barcode) {
>  # save the return
>  #
>     ( $returned, $messages, $issueinformation, $borrower ) =
> -      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode);
>   # do the return
> +      AddReturn( $barcode, $userenv_branch, $exemptfine,
> $dropboxmode,$override);     # do the return
>     my $homeorholdingbranchreturn =
> C4::Context->preference('HomeOrHoldingBranchReturn') or 'homebranch';
>
> +            my @ips=split /,|\|/,
> C4::Context->preference("CI-3M:AuthorizedIPs");
> +            #my $pid=fork();
> +            #unless($pid && $remotehost=~qr(^$ips$)){
> +            #if (!$pid && any{ $remotehost eq $_ }@ips ){
> +            if (any{ $remotehost eq $_ }@ips ){
> +                system("../services/magnetise.pl $remotehost in");
> +                #die 0;
> +            }
>     # get biblio description
> -    my $biblio = GetBiblioFromItemNumber($itemnumber);
> +    $biblio = GetBiblioFromItemNumber($itemnumber);
>     # fix up item type for display
>     $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ?
> $biblio->{'itype'} : $biblio->{'itemtype'};
>
> @@ -242,7 +258,7 @@ if ($barcode) {
>         $input{return_overdue} = 1 if ($duedate and $duedate lt
> $today->output('iso'));
>         push( @inputloop, \%input );
>     }
> -    elsif ( !$messages->{'BadBarcode'} ) {
> +    elsif ( !$messages->{'BadBarcode'} and ! $messages->{'Wrongbranch'} )
> {
>         $input{duedate}   = 0;
>         $returneditems{0} = $barcode;
>         $riduedate{0}     = 0;
> @@ -260,6 +276,18 @@ if ($barcode) {
>  }
>  $template->param( inputloop => \@inputloop );
>
> +
> +# Is there a circulation note?
> +my $itemnumber = GetItemnumberFromBarcode($barcode);
> +my $biblionumber = GetBiblionumberFromItemnumber($itemnumber);
> +my $record = GetMarcBiblio($biblionumber);
> +my $frameworkcode = GetFrameworkCode($biblionumber);
> +my $circnotefield = GetRecordValue('circnote', $record, $frameworkcode);
> +if (defined @$circnotefield[0]) {
> +   $template->param(circnote => @$circnotefield[0]->{'subfield'});
> +}
> +
> +
>  my $found    = 0;
>  my $waiting  = 0;
>  my $reserved = 0;
> @@ -283,9 +311,13 @@ if ( $messages->{'NeedsTransfer'} ){
>  }
>
>  if ( $messages->{'Wrongbranch'} ){
> -    $template->param(
> -        wrongbranch => 1,
> -    );
> +       $template->param(
> +               wrongbranch =>
> $branches->{$messages->{'Wrongbranch'}->{'Wrongbranch'}}->{'branchname'},
> +               rightbranch =>
> $branches->{$messages->{'Wrongbranch'}->{'Rightbranch'}}->{'branchname'},
> +               barcode     => $barcode,
> +               exemptfine  => $exemptfine,
> +               dropboxmode => $dropboxmode,
> +       );
>  }
>
>  # case of wrong transfert, if the document wasn't transfered to the right
> library (according to branchtransfer (tobranch) BDD)
> @@ -340,7 +372,7 @@ if ( $messages->{'ResFound'}) {
>                 reserved     => 1,
>             );
>         }
> -
> +        my $debarred = CheckBorrowerDebarred($reserve->{borrowernumber});
>         # same params for Waiting or Reserved
>         $template->param(
>             found          => 1,
> @@ -357,17 +389,18 @@ if ( $messages->{'ResFound'}) {
>             borcity        => $borr->{'city'},
>             borzip         => $borr->{'zipcode'},
>             borcnum        => $borr->{'cardnumber'},
> -            debarred       => $borr->{'debarred'},
> +            debarred       => $debarred,
>             gonenoaddress  => $borr->{'gonenoaddress'},
>             barcode        => $barcode,
> -            destbranch     => $reserve->{'branchcode'},
> +            reservenumber  => $reserve->{'reservenumber'},
> +            destbranch    => $reserve->{'branchcode'},
>             borrowernumber => $reserve->{'borrowernumber'},
>             itemnumber     => $reserve->{'itemnumber'},
>             reservenotes   => $reserve->{'reservenotes'},
>         );
>     } # else { ; }  # error?
>  }
> -
> +$borrower->{'flags'}= C4::Members::patronflags($borrower);
>  # Error Messages
>  my @errmsgloop;
>  foreach my $code ( keys %$messages ) {
> @@ -393,6 +426,35 @@ foreach my $code ( keys %$messages ) {
>     elsif ( $code eq 'WasTransfered' ) {
>         ;    # FIXME... anything to do here?
>     }
> +    elsif ( $code eq 'NotForLoan' ) {
> +        my $fw               =
> GetFrameworkCode($biblio->{'biblionumber'});
> +        my $category         = GetAuthValCode('items.notforloan',$fw);
> +        my $authorizedvalues = GetAuthorisedValues($category,
> $messages->{$code});
> +
> +        foreach my $authvalue (@$authorizedvalues){
> +            $err{notforloan} = $authvalue->{lib} if
> $authvalue->{'authorised_value'} eq $messages->{$code};
> +        }
> +    }
> +    elsif ( $code eq 'Damaged' ) {
> +        my $fw               =
> GetFrameworkCode($biblio->{'biblionumber'});
> +        my $category         = GetAuthValCode('items.damaged',$fw);
> +        my $authorizedvalues = GetAuthorisedValues($category,
> $messages->{$code});
> +
> +        foreach my $authvalue (@$authorizedvalues){
> +            $err{damaged} = $authvalue->{lib} if
> $authvalue->{'authorised_value'} eq $messages->{$code};
> +        }
> +    }
> +    elsif( $code eq 'Debarred' ){
> +        $err{debarred}            = format_date($messages->{'Debarred'});
> +        $err{debarcardnumber}     = $borrower->{cardnumber};
> +        $err{debarborrowernumber} = $borrower->{borrowernumber};
> +        $err{debarname}           = "$borrower->{firstname}
> $borrower->{surname}";
> +    }
> +    elsif( $code eq 'HaveFines' ){
> +        $err{havefines}       =
> $borrower->{'flags'}->{'CHARGES'}->{'amount'} . %{GetCurrency()}->{symbol};
> +        $err{finecardnumber} = $borrower->{cardnumber};
> +        $err{finename}       = "$borrower->{firstname}
> $borrower->{surname}";
> +    }
>     elsif ( $code eq 'wthdrawn' ) {
>         $err{withdrawn} = 1;
>         $exit_required_p = 1;
> @@ -414,7 +476,6 @@ foreach my $code ( keys %$messages ) {
>     }
>     elsif ( $code eq 'Wrongbranch' ) {
>     }
> -
>     else {
>         die "Unknown error code $code";    # note we need all the (empty)
> elsif's above, or we die.
>         # This forces the issue of staying in sync w/ Circulation.pm
> @@ -428,14 +489,10 @@ $template->param( errmsgloop => \@errmsgloop );
>
>  # patrontable ....
>  if ($borrower) {
> -    my $flags = $borrower->{'flags'};
>     my @flagloop;
> -    my $flagset;
> +    my $flags=$borrower->{flags};
>     foreach my $flag ( sort keys %$flags ) {
>         my %flaginfo;
> -        unless ($flagset) { $flagset = 1; }
> -        $flaginfo{redfont} = ( $flags->{$flag}->{'noissues'} );
> -        $flaginfo{flag}    = $flag;
>         if ( $flag eq 'CHARGES' ) {
>             $flaginfo{msg}            = $flag;
>             $flaginfo{charges}        = 1;
> @@ -450,14 +507,29 @@ if ($borrower) {
>             foreach my $item (@$items) {
>                 my $biblio = GetBiblioFromItemNumber(
> $item->{'itemnumber'});
>                 push @waitingitemloop, {
> -                    biblionum => $biblio->{'biblionumber'},
> -                    barcode   => $biblio->{'barcode'},
> -                    title     => $biblio->{'title'},
> -                    brname    => $branches->{ $biblio->{'holdingbranch'}
> }->{'branchname'},
> +                    biblionumber=> $biblio->{'biblionumber'},
> +                    author      => $biblio->{'author'},
> +                    itemtype    => $item->{'ccode'},
> +                    reservedate => format_date($item->{'reservedate'}),
> +                    waitingdate => format_date($item->{'waitingdate'}),
> +                    barcode     => $item->{'barcode'},
> +                    maxpickupdate=> format_date(
> sprintf("%d-%02d-%02d",GetMaxPickupDate($item->{'waitingdate'},
> $borrower->{borrowernumber},$item ))),
> +                    title       => $biblio->{'title'},
> +                    brname      => $branches->{ $item->{'branchcode'}
> }->{'branchname'},
> +                    waitinghere => ($item->{'branchcode'} eq
> $userenv_branch)
>                 };
>             }
>             $flaginfo{itemloop} = \@waitingitemloop;
>         }
> +        elsif ( $flag =~ /DEBARRED|LOST|GNA/ ) {
> +            if ($flag ne "GNA"){
> +                $flag=lc($flag);
> +            }
> +            else{
> +                $flag="gonenoaddress";
> +            }
> +            %flaginfo=( $flag =>1,
> $flag."comment"=>$borrower->{$flag."comment"},dateend=>$flags->{uc($flag)}->{dateend});
> +        }
>         elsif ( $flag eq 'ODUES' ) {
>             my $items = $flags->{$flag}->{'itemlist'};
>             my @itemloop;
> @@ -483,7 +555,6 @@ if ($borrower) {
>         push( @flagloop, \%flaginfo );
>     }
>     $template->param(
> -        flagset          => $flagset,
>         flagloop         => \@flagloop,
>         riborrowernumber => $borrower->{'borrowernumber'},
>         riborcnum        => $borrower->{'cardnumber'},
> @@ -494,7 +565,7 @@ if ($borrower) {
>  }
>
>  #set up so only the last 8 returned items display (make for faster loading
> pages)
> -my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow')
> ) ? C4::Context->preference('numReturnedItemsToShow') : 8;
> +my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow')
> ) ? C4::Context->preference('numReturnedItemsToShow') : 10;
>  my $count = 0;
>  my @riloop;
>  foreach ( sort { $a <=> $b } keys %returneditems ) {
> @@ -521,19 +592,25 @@ foreach ( sort { $a <=> $b } keys %returneditems ) {
>         else {
>             $ri{borrowernumber} = $riborrowernumber{$_};
>         }
> -
>         #        my %ri;
>         my $biblio =
> GetBiblioFromItemNumber(GetItemnumberFromBarcode($bar_code));
> +        my $item = GetItem(GetItemnumberFromBarcode($bar_code));
>         # fix up item type for display
>         $biblio->{'itemtype'} =
> C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} :
> $biblio->{'itemtype'};
>         $ri{itembiblionumber} = $biblio->{'biblionumber'};
>         $ri{itemtitle}        = $biblio->{'title'};
>         $ri{itemauthor}       = $biblio->{'author'};
> -        $ri{itemtype}         = $biblio->{'itemtype'};
>         $ri{itemnote}         = $biblio->{'itemnotes'};
> -        $ri{ccode}            = $biblio->{'ccode'};
>         $ri{itemnumber}       = $biblio->{'itemnumber'};
> +        $ri{itemtype}         = $item->{'itype'};
> +        $ri{ccode}            = $item->{'ccode'};
> +        $ri{itemcallnumber}   = $item->{'itemcallnumber'};
> +        $ri{homebranch}       = $item->{'homebranch'};
> +        $ri{holdingbranch}    = $item->{'holdingbranch'};
>         $ri{barcode}          = $bar_code;
> +        my $shelflocations    =
> GetKohaAuthorisedValues('items.location','');
> +        $ri{itemlocation}     = $shelflocations->{$biblio->{'location'}};
> +
>     }
>     else {
>         last;
> diff --git
> a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tmpl
> index fc7e41f..ad7001c 100644
> ---
> a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tmpl
> +++
> b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tmpl
> @@ -48,6 +48,7 @@
>                        return false;
>                });
>
> +        $('#selectlibrary input[type=submit]').hide();
>        });
>  </script>
>  <style type="text/css">td { text-align: center; }</style>
> @@ -68,13 +69,18 @@
>     <form method="get" action="/cgi-bin/koha/admin/
> branch_transfer_limits.pl" id="selectlibrary">
>         <label for="branchselect">Select a library :</label>
>             <select name="branchcode" id="branchselect">
> +            <option value="">Choose one</option>
>                <!-- TMPL_LOOP NAME="branch_loop" -->
> +            <!-- TMPL_IF EXPR="value eq branchcode" -->
> +                <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 -->
>                <!-- /TMPL_LOOP -->
>             </select>
>            <input type="submit" value="Choose" />
>     </form>
> -
> +<!-- TMPL_IF NAME="branchcode" -->
>  <p class="help">Check the boxes for the libraries you accept to checkin
> items from.</p>
>  <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>
>
> @@ -99,11 +105,11 @@
>                        </thead>
>
>                        <tbody>
> -                                       <!-- TMPL_LOOP
> NAME="to_branch_loop" -->
> +                                       <!-- TMPL_LOOP
> NAME="from_branch_loop" -->
>                                                <!-- TMPL_UNLESS
> NAME="__odd__" --><tr class="highlight"><!-- TMPL_ELSE
>  --><tr><!-- /TMPL_UNLESS -->
> -                                                       <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>
> -                                                       <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>
> +                                                       <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>
> +                                                       <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>
>                                                </tr>
>                                        <!-- /TMPL_LOOP -->
>                        </tbody>
> @@ -121,6 +127,7 @@
>                </div>
>   </div>
>  </div>
> +<!-- /TMPL_IF -->
>  <div class="yui-b">
>   <!-- TMPL_INCLUDE NAME="admin-menu.inc" -->
>  </div>
> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tmpl
> index ad675d1..dcb57a2 100644
> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tmpl
> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tmpl
> @@ -24,7 +24,8 @@
>        <!-- TMPL_IF NAME="error" -->
>            <div class="dialog alert">Cloning of issuing rules failed!</div>
>        <!-- TMPL_ELSE -->
> -           <div class="dialog message"><p>The rules have been
> cloned.</p></div>
> +           <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>
> +           <script language="javascript">document.location.href =
> "/cgi-bin/koha/admin/smart-rules.pl?branch=<!-- TMPL_VAR NAME="tobranch"
> -->";</script>
>        <!-- /TMPL_IF -->
>        <a href="/cgi-bin/koha/admin/smart-rules.pl">Return to Issuing
> rules</a>
>     <!-- TMPL_ELSE -->
> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl
> index 895ceb9..03a6de9 100644
> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl
> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl
> @@ -9,7 +9,7 @@
>  //<![CDATA[
>  $(document).ready(function() {
>         $('#selectlibrary').find("input:submit").hide();
> -        $('#branch').change(function() {
> +        $('#branchcode').change(function() {
>                 $('#selectlibrary').submit();
>         });
>         $('#filter').keyup(function() {
> @@ -19,6 +19,9 @@ $(document).ready(function() {
>             $('.issues').show();
>             $('.fines').show();
>             $('.reserves').show();
> +            $('.issues :input').removeAttr('disabled',true);
> +            $('.fines :input').removeAttr('disabled',true);
> +            $('.reserves :input').removeAttr('disabled',true);
>             $(this).parent().attr('class','ui-tabs-selected');
>             $('#issuesfilter').parent().attr('class',null);
>             $('#finesfilter').parent().attr('class',null);
> @@ -28,6 +31,9 @@ $(document).ready(function() {
>             $('.issues').show();
>             $('.fines').hide();
>             $('.reserves').hide();
> +            $('.issues :input').removeAttr('disabled',true);
> +            $('.fines :input').attr('disabled',true);
> +            $('.reserves :input').attr('disabled',true);
>             $(this).parent().attr('class','ui-tabs-selected');
>             $('#nofilter').parent().attr('class',null);
>             $('#finesfilter').parent().attr('class',null);
> @@ -37,6 +43,9 @@ $(document).ready(function() {
>             $('.issues').hide();
>             $('.fines').show();
>             $('.reserves').hide();
> +            $('.issues :input').attr('disabled',true);
> +            $('.fines :input').removeAttr('disabled',true);
> +            $('.reserves :input').attr('disabled',true);
>             $(this).parent().attr('class','ui-tabs-selected');
>             $('#issuesfilter').parent().attr('class',null);
>             $('#nofilter').parent().attr('class',null);
> @@ -46,11 +55,99 @@ $(document).ready(function() {
>             $('.issues').hide();
>             $('.fines').hide();
>             $('.reserves').show();
> +            $('.issues :input').attr('disabled',true);
> +            $('.fines :input').attr('disabled',true);
> +            $('.reserves :input').removeAttr('disabled',true);
>             $(this).parent().attr('class','ui-tabs-selected');
>             $('#issuesfilter').parent().attr('class',null);
>             $('#finesfilter').parent().attr('class',null);
>             $('#nofilter').parent().attr('class',null);
>         });
> +
> +        // Inline editor
> +        var editor = false;
> +        $('#smartrules>tbody>tr>td.editable').click(function() {
> +            if ( ! editor ) {
> +                var td = $(this);
> +                var tdvalue = td.text().trim();
> +                td.text('');
> +
> +                var type;
> +                if ( $.inArray('boolean', td.attr('class').split(' ')) !=
> -1 ) { // If the td is boolean, we display a checkbox
> +                    editor = $('<input id="inlineeditor" type="checkbox"
> /\>');
> +                    editor.attr('checked', tdvalue == 'Yes' ? 'checked' :
> '');
> +                    type = 'boolean';
> +                } else if ( $.inArray('triple', td.attr('class').split('
> ')) != -1 ) { // else if it is a triple, we display a listbox
> +                    var selectedn = tdvalue ==  ''   ?
> 'selected="selected"' : '';
> +                    var selected1 = tdvalue == 'Yes' ?
> 'selected="selected"' : '';
> +                    var selected0 = tdvalue == 'No'  ?
> 'selected="selected"' : '';
> +                    var str  = '<select id="inlineeditor">';
> +                        str += '<option value=""  ' + selectedn +
> '></option>';
> +                        str += '<option value="1" ' + selected1 +
> '>Yes</option>';
> +                        str += '<option value="0" ' + selected0 +
> '>No</option>';
> +                        str += '</select>';
> +                    editor = $(str);
> +                    type = 'triple';
> +                } else { // else we display a textbox
> +                    editor = $('<input id="inlineeditor" type="text"
> size="4" /\>');
> +                    editor.attr('value', tdvalue);
> +                }
> +
> +                editor.focus();
> +
> +                editor.keyup(function(e) {   // on press
> +                    if ( e.keyCode == 13 ) { // enter
> +
> +                        // let's build the atomic rule
> +                        var branchcode   = $('#branchcode').val();
> +                        var categorycode =
> td.parent().children('td.categorycode').children('span').text();
> +                        var itemtype     =
> td.parent().children('td.itemtype').children('span').text();
> +                        var varname      = td.attr('class').split(' ')[0];
> +                        var inputvalue;
> +                        switch ( type ) {
> +                            case 'boolean':
> +                                inputvalue = editor.attr('checked') ? 1 :
> 0;
> +                                break;
> +                            default:
> +                                inputvalue = editor.val();
> +                                break;
> +                        }
> +
> +                        // post it to the server
> +                        $.ajax({
> +                            url: '/cgi-bin/koha/admin/
> smart-rules-service.pl',
> +                            type: "POST",
> +                            async: false,
> +                            data:
> "branchcode="+branchcode+"&categorycode="+categorycode+"&itemtype="+itemtype+"&varname="+varname+"&inputvalue="+inputvalue,
> +                            success: function(result) {
> +
> +                                // repopulate the td with data
> +                                switch ( type ) {
> +                                    case 'boolean':
> +                                        td.text(result == '1' ? 'Yes' :
> 'No');
> +                                        break;
> +                                    case 'triple':
> +                                        switch ( result ) {
> +                                            case '' : td.text('');
>  break;
> +                                            case '1': td.text('Yes');
> break;
> +                                            case '0': td.text('No');
>  break;
> +                                        }
> +                                        break;
> +                                    default:
> +                                        td.text(result);
> +                                        break;
> +                                }
> +
> +                                editor.remove();
> +                                editor = false;
> +                            }
> +                        });
> +                    }
> +                });
> +
> +                td.append(editor);
> +            }
> +        });
>  });
>  //]]>
>  </script>
> @@ -74,24 +171,10 @@ $(document).ready(function() {
>             Defining default circulation and fine rules
>         <!-- /TMPL_IF -->
>     </h1>
> -    <div class="help">
> -        <p>The rules are applied from most specific to less specific,
> using the first found in this order:</p>
> -        <ul>
> -            <li>same library, same patron type, same item type</li>
> -            <li>same library, same patron type, default item type</li>
> -            <li>same library, default patron type, same item type</li>
> -            <li>same library, default patron type, default item type</li>
> -            <li>default library, same patron type, same item type</li>
> -            <li>default library, same patron type, default item type</li>
> -            <li>default library, default patron type, same item type</li>
> -            <li>default library, default patron type, default item
> type</li>
> -        </ul>
> -        <p>To modify a rule, create a new one with the same patron type
> and item type.</p>
> -    </div>
>     <div id="bloc100">
>         <form method="get" action="/cgi-bin/koha/admin/smart-rules.pl"
> id="selectlibrary">
>         Select a library :
> -            <select name="branch" id="branch" style="width:20em;">
> +            <select name="branchcode" id="branchcode" style="width:20em;">
>                 <option value="*">Default</option>
>             <!-- TMPL_LOOP NAME="branchloop" -->
>                 <!-- 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
> -->
> @@ -107,288 +190,218 @@ $(document).ready(function() {
>                 <li><a id="issuesfilter">Issues</a></li>
>                 <li><a id="finesfilter">Fines</a></li>
>                 <li><a id="reservesfilter">Reserves</a></li>
> -                <div style="text-align:right;"><label for="filter">Filter:
> </label><input type="text" name="filter" id="filter" /></div>
> +                <div style="text-align:right;">
> +                    <label for="filter" style="float:none;">Filter:
> </label>
> +                    <input type="text" name="filter" id="filter" />
> +                </div>
>             </ul>
>             <div class="tabs-container">
> -            <form method="post" action="/cgi-bin/koha/admin/
> smart-rules.pl">
> -            <input type="hidden" name="op" value="add" />
> -            <table id="smartrules" width="100%">
> -                <thead>
> -                    <tr>
> -                        <th>Patron Category</th>
> -                        <th>Item Type</th>
> -                        <th class="issues">Current Checkouts Allowed</th>
> -                        <th class="issues">Loan Period (day)</th>
> -                        <th class="fines">Fine Amount</th>
> -                        <th class="fines">Fine Charging Interval</th>
> -                        <th class="fines">Fine Grace period (day)</th>
> -                        <th class="fines">Suspension in Days (day)</th>
> -                        <th class="issues">Renewals Allowed (count)</th>
> -                        <th class="reserves">Holds Allowed (count)</th>
> -                        <th class="issues">Rental Discount (%)</th>
> -                        <th>&nbsp;</th>
> -                    </tr>
> -                </thead>
> -                <tbody>
> -                               <!-- TMPL_LOOP NAME="rules" -->
> -                                       <!-- TMPL_UNLESS NAME="__odd__" -->
> -                                       <tr class="highlight">
> -                                       <!-- TMPL_ELSE -->
> -                                       <tr>
> -                                       <!-- /TMPL_UNLESS -->
> -                                                       <td><!-- TMPL_IF
> NAME="default_humancategorycode" -->
> -
> <em>Default</em>
> -                                                               <!--
> TMPL_ELSE -->
> -
> <!-- TMPL_VAR NAME="humancategorycode" -->
> -                                                               <!--
> /TMPL_IF -->
> -                                                       </td>
> -                                                       <td><!-- TMPL_IF
> NAME="default_humanitemtype" -->
> -
> <em>Default</em>
> -                                                               <!--
> TMPL_ELSE -->
> -
> <!-- TMPL_VAR NAME="humanitemtype" -->
> -                                                               <!--
> /TMPL_IF -->
> -                                                       </td>
> -                                                           <td
> class="issues"><!-- TMPL_IF NAME="unlimited_maxissueqty" -->
> +                    <table id="smartrules" width="100%">
> +                        <thead>
> +                            <tr>
> +                                <th>Patron category</th>
> +                                <th>Item type</th>
> +                                <th class="issues">Current checkouts
> allowed</th>
> +                                <th class="issues">Loan period (day)</th>
> +                                <th class="fines">Fine amount</th>
> +                                <th class="fines">Fine charging
> interval</th>
> +                                <th class="fines">Grace period (day)</th>
> +                                <th class="fines">Suspension duration
> (day)</th>
> +                                <th class="issues">Renewals allowed
> (count)</th>
> +                                <th class="issues">Renewals period
> (days)</th>
> +                                <th class="reserves">Holds allowed
> (count)</th>
> +                                <th class="reserves">Holds pickup delay
> (day)</th>
> +                                <th class="reserves">Allow on shelf
> holds</th>
> +                                <th class="reserves">Holds restricted to
> library</th>
> +                                <th class="issues">Rental Discount
> (%)</th>
> +                                <th>&nbsp;</th>
> +                            </tr>
> +                        </thead>
> +                        <tbody>
> +                        <!-- TMPL_LOOP NAME="rules" -->
> +                            <!-- TMPL_UNLESS NAME="__odd__" -->
> +                            <tr class="highlight">
> +                            <!-- TMPL_ELSE -->
> +                            <tr>
> +                            <!-- /TMPL_UNLESS -->
> +                                    <td class="categorycode">
> +                                        <span style="display:none;"><!--
> TMPL_VAR NAME="categorycode" --></span>
> +                                        <!-- TMPL_IF
> NAME="default_humancategorycode" -->
> +                                            <em>Default</em>
> +                                        <!-- TMPL_ELSE -->
> +                                            <!-- TMPL_VAR
> NAME="humancategorycode" -->
> +                                        <!-- /TMPL_IF -->
> +                                    </td>
> +                                    <td class="itemtype">
> +                                        <span style="display:none;"><!--
> TMPL_VAR NAME="itemtype" --></span>
> +                                        <!-- TMPL_IF
> NAME="default_humanitemtype" -->
> +                                            <em>Default</em>
> +                                        <!-- TMPL_ELSE -->
> +                                            <!-- TMPL_VAR
> NAME="humanitemtype" -->
> +                                        <!-- /TMPL_IF -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_maxissueqty" -->
> +                                    <td class="maxissueqty editable issues
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="maxissueqty editable
> issues">
> +                                    <!-- /TMPL_IF -->
> +                                        <!-- TMPL_IF
> NAME="unlimited_maxissueqty" -->
>                                             Unlimited
>                                         <!-- TMPL_ELSE -->
>                                             <!-- TMPL_VAR
> NAME="maxissueqty" -->
>                                         <!-- /TMPL_IF -->
>                                     </td>
> -                                    <td class="issues"><!-- TMPL_IF
> NAME="issuelength" --><!-- TMPL_VAR NAME="issuelength" --> <!-- /TMPL_IF
> --></td>
> -                                    <td class="fines"><!-- TMPL_VAR
> NAME="fine" --></td>
> -                                    <td class="fines"><!-- TMPL_IF
> NAME="chargeperiod" --><!-- TMPL_VAR NAME="chargeperiod" --> <!-- /TMPL_IF
> --></td>
> -                                    <td class="fines"><!-- TMPL_IF
> NAME="firstremind" --><!-- TMPL_VAR NAME="firstremind" --> <!-- /TMPL_IF
> --></td>
> -                                    <td class="fines"><!-- TMPL_IF
> NAME="finedays" --> <!-- TMPL_VAR NAME="finedays" --> <!-- /TMPL_IF --></td>
> -                                    <td class="issues"><!-- TMPL_IF
> NAME="renewalsallowed" --><!-- TMPL_VAR NAME="renewalsallowed" --> <!--
> /TMPL_IF --></td>
> -                                    <td class="reserves"><!-- TMPL_IF
> NAME="reservesallowed" --><!-- TMPL_VAR NAME="reservesallowed" --> <!--
> /TMPL_IF --></td>
> -                                                       <td
> class="issues"><!-- TMPL_VAR NAME="rentaldiscount" --></td>
> -                                                       <td>
> -                                                               <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="branch" -->">Delete</a>
> -                                                       </td>
> -                       </tr>
> -               <!-- /TMPL_LOOP -->
> -                </tbody>
> -                <tfoot>
> -                <tr>
> -                    <td>
> -                        <select name="categorycode">
> -                            <option value="*">Default</option>
> -                        <!-- TMPL_LOOP NAME="categoryloop" -->
> -                            <option value="<!-- TMPL_VAR
> NAME="categorycode" -->"><!-- TMPL_VAR NAME="description" --></option>
> -                        <!-- /TMPL_LOOP -->
> -                        </select>
> -                    </td>
> -                    <td>
> -                        <select name="itemtype" style="width:13em;">
> -                            <option value="*">Default</option>
> -                        <!-- TMPL_LOOP NAME="itemtypeloop" -->
> -                            <option value="<!-- TMPL_VAR NAME="itemtype"
> -->"><!-- TMPL_VAR NAME="description" --></option>
> -                        <!-- /TMPL_LOOP -->
> -                        </select>
> -                    </td>
> -                        <td class="issues"><input name="maxissueqty"
> size="3" /></td>
> -                                <td class="issues"><input
> name="issuelength" size="3" /> </td>
> -                                <td class="fines"><input name="fine"
> size="4" /></td>
> -                                <td class="fines"><input
> name="chargeperiod" size="2" /></td>
> -                                <td class="fines"><input
> name="firstremind" size="2" /> </td>
> -                                <td class="fines"><input name="finedays"
> size="3" /> </td>
> -                                <td class="issues"><input
> name="renewalsallowed" size="2" /></td>
> -                                <td class="reserves"><input
> name="reservesallowed" size="2" /></td>
> -                   <td><input class="issues" name="rentaldiscount"
> size="2" /></td>
> -                    <td><input type="hidden" name="branch" value="<!--
> TMPL_VAR NAME="branch" -->"/><input type="submit" value="Add" class="submit"
> /></td>
> -                </tr>
> -                </tfoot>
> -            </table>
> -        </form>
> +                                    <!-- TMPL_IF
> NAME="herited_issuelength" -->
> +                                    <td class="issuelength editable issues
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="issuelength editable
> issues">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="issuelength" -->
> +                                    </td>
> +                                    <!-- TMPL_IF NAME="herited_fine" -->
> +                                    <td class="fine editable fines
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="fine editable fines">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="fine" -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_chargeperiod" -->
> +                                    <td class="chargeperiod editable fines
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="chargeperiod editable
> fines">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="chargeperiod" -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_firstremind" -->
> +                                    <td class="firstremind editable fines
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="firstremind editable
> fines">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="firstremind" -->
> +                                    </td>
> +                                    <!-- TMPL_IF NAME="herited_finedays"
> -->
> +                                    <td class="finedays editable fines
> herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="finedays editable fines">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="finedays" -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_renewalsallowed" -->
> +                                    <td class="renewalsallowed editable
> issues herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="renewalsallowed editable
> issues">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="renewalsallowed"
> -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_renewalperiod" -->
> +                                    <td class="renewalperiod editable
> issues herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="renewalperiod editable
> issues">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="renewalperiod" -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_reservesallowed" -->
> +                                    <td class="reservesallowed editable
> reserves herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="reservesallowed editable
> reserves">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="reservesallowed"
> -->
> +                                    </td>
> +                                     <!-- TMPL_IF
> NAME="herited_holdspickupdelay" -->
> +                                    <td class="holdspickupdelay editable
> reserves herited">
> +                                    <!--TMPL_ELSE-->
> +                                    <td class="holdspickupdelay editable
> reserves">
> +                                    <!--/TMPL_IF-->
> +                                    <!-- TMPL_VAR NAME="holdspickupdelay"
> -->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_allowonshelfholds" -->
> +                                    <td class="allowonshelfholds editable
> reserves triple herited">
> +                                    <!--TMPL_ELSE-->
> +                                    <td class="allowonshelfholds editable
> reserves triple">
> +                                   <!--/TMPL_IF-->
> +                                    <!-- TMPL_IF NAME="allowonshelfholds"
> -->
> +                                    Yes
> +                                    <!--TMPL_ELSE-->
> +                                    No
> +                                    <!--/TMPL_IF-->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_holdrestricted" -->
> +                                    <td class="holdrestricted editable
> reserves boolean herited">
> +                                    <!--TMPL_ELSE-->
> +                                     <td class="holdrestricted editable
> reserves boolean">
> +                                    <!--/TMPL_IF-->
> +                                    <!-- TMPL_IF NAME="holdrestricted" -->
> +                                    Yes
> +                                    <!--TMPL_ELSE-->
> +                                    No
> +                                    <!--/TMPL_IF-->
> +                                    </td>
> +                                    <!-- TMPL_IF
> NAME="herited_rentaldiscount" -->
> +                                    <td class="rentaldiscount editable
> issues herited">
> +                                    <!-- TMPL_ELSE -->
> +                                    <td class="rentaldiscount editable
> issues">
> +                                    <!-- /TMPL_IF -->
> +                                    <!-- TMPL_VAR NAME="rentaldiscount"
> -->
> +                                    </td>
> +                                    <td>
> +                                        <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>
> +                                    </td>
> +                                </tr>
> +                            <!-- /TMPL_LOOP -->
> +                        </tbody>
> +                        <form method="post" name="inputrules"
> action="/cgi-bin/koha/admin/smart-rules.pl">
> +                            <input type="hidden" name="op" value="add" />
> +                        <tfoot>
> +                            <tr>
> +                                <td>
> +                                    <select name="categorycode"
> id="categorycode" style="width:12em;">
> +                                        <option value="*">Default</option>
> +                                    <!-- TMPL_LOOP NAME="categoryloop" -->
> +                                        <!-- TMPL_IF Name="selected"-->
> +                                        <option value="<!-- TMPL_VAR
> NAME="categorycode" -->" selected="selected"><!-- TMPL_VAR
> NAME="description" --></option>
> +                                        <!--TMPL_ELSE --> <option
> value="<!-- TMPL_VAR NAME="categorycode" -->" ><!-- TMPL_VAR
> NAME="description" --></option>
> +                                        <!-- /TMPL_IF -->
> +                                    <!-- /TMPL_LOOP -->
> +                                    </select>
> +                                </td>
> +                                <td>
> +                                    <select name="itemtype"
> style="width:12em;">
> +                                        <option value="*">Default</option>
> +                                    <!-- TMPL_LOOP NAME="itemtypeloop" -->
> +                                        <!-- TMPL_IF Name="selected"-->
> +                                        <option value="<!-- TMPL_VAR
> NAME="itemtype" -->" selected="selected"><!-- TMPL_VAR NAME="description"
> --></option>
> +                                        <!--TMPL_ELSE --> <option
> value="<!-- TMPL_VAR NAME="itemtype" -->"><!-- TMPL_VAR NAME="description"
> --></option>
> +                                        <!-- /TMPL_IF -->
> +                                    <!-- /TMPL_LOOP -->
> +                                    </select>
> +                                </td>
> +                                <td class="issues"><input
> name="maxissueqty" size="3" value="<!-- TMPL_VAR NAME="maxissueqty"
> -->"/></td>
> +                                <td class="issues"><input
> name="issuelength" size="3" value="<!-- TMPL_VAR NAME="issuelength" -->"/>
> </td>
> +                                <td class="fines"><input name="fine"
> size="4" value="<!-- TMPL_VAR NAME="fine" -->"/></td>
> +                                <td class="fines"><input
> name="chargeperiod" size="2" value="<!-- TMPL_VAR NAME="chargeperiod"
> -->"/></td>
> +                                <td class="fines"><input
> name="firstremind" size="2" value="<!-- TMPL_VAR NAME="firstremind" -->"/>
> </td>
> +                                <td class="fines"><input name="finedays"
> size="3" value="<!-- TMPL_VAR NAME="finedays" -->"/> </td>
> +                                <td class="issues"><input
> name="renewalsallowed" size="2" value="<!-- TMPL_VAR NAME="renewalsallowed"
> -->"/></td>
> +                                <td class="issues"><input
> name="renewalperiod" size="2" value="<!-- TMPL_VAR NAME="renewalperiod"
> -->"/></td>
> +                                <td class="reserves"><input
> name="reservesallowed" size="2" value="<!-- TMPL_VAR NAME="reservesallowed"
> -->"/></td>
> +                                <td class="reserves"><input
> name="holdspickupdelay" size="2" value="<!-- TMPL_VAR
> NAME="holdspickupdelay" -->"/></td>
> +                                <td class="reserves">
> +                                    <select name="allowonshelfholds">
> +                                        <option value=""></option>
> +                                        <option value="1">Yes</option>
> +                                        <option value="0">No</option>
> +                                    </select>
> +                                </td>
> +                                <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>
> +                                       <td class="issues"><input
> name="rentaldiscount" size="2" /></td>
> +                                <td><input type="hidden" name="branchcode"
> value="<!-- TMPL_VAR NAME="branchcode" -->"/><input type="submit"
> value="Add" class="submit" /></td>
> +                            </tr>
> +                        </tfoot>
> +                </form>
> +                    </table>
>             </div><!-- tabs-container -->
>         </div><!-- toptabs -->
>     </div>
> -    <div class="help">
> -        <h4>Defaults for this library</h4>
> -        <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>
> -    </div>
> -    <div>
> -        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
> -            <input type="hidden" name="op" value="set-branch-defaults" />
> -            <input type="hidden" name="branch" value="<!-- TMPL_VAR
> NAME="branch" -->"/>
> -            <table>
> -                <tr>
> -                    <th>&nbsp;</th>
> -                    <th>Total Current Checkouts Allowed</th>
> -                    <th>Hold Policy</th>
> -                    <th>&nbsp;</th>
> -                    <th>&nbsp;</th>
> -                </tr>
> -                <tr>
> -                    <td><em>Defaults<!-- TMPL_UNLESS NAME="default_rules"
> --> (not set)<!-- /TMPL_IF --></em></td>
> -                    <td><input type="text" name="maxissueqty" size="3"
> value="<!-- TMPL_VAR NAME="default_maxissueqty" -->"/></td>
> -                    <td>
> -                        <select name="holdallowed">
> -                            <!-- TMPL_IF NAME="default_holdallowed_any"
> -->
> -                            <option value="2" selected="selected">
> -                            <!-- TMPL_ELSE -->
> -                            <option value="2">
> -                            <!-- /TMPL_IF -->
> -                                From Any Library
> -                            </option>
> -                            <!-- TMPL_IF NAME="default_holdallowed_same"
> -->
> -                            <option value="1" selected="selected">
> -                            <!-- TMPL_ELSE -->
> -                            <option value="1">
> -                            <!-- /TMPL_IF -->
> -                                From Home Library
> -                            </option>
> -                            <!-- TMPL_IF NAME="default_holdallowed_none"
> -->
> -                            <option value="0" selected="selected">
> -                            <!-- TMPL_ELSE -->
> -                            <option value="0">
> -                            <!-- /TMPL_IF -->
> -                                No Holds Allowed
> -                            </option>
> -                        </select>
> -                    </td>
> -                    <td><input type="submit" value="Save" class="submit"
> /></td>
> -                    <td>
> -                        <a class="button" href="/cgi-bin/koha/admin/
> smart-rules.pl?op=delete-branch-cat&amp;categorycode=*&amp;branch=<!--
> TMPL_VAR NAME="branch" -->">Unset</a>
> -                    </td>
> -                </tr>
> -            </table>
> -        </form>
> -    </div>
> -    <!-- TMPL_IF NAME="show_branch_cat_rule_form" -->
> -    <div class="help">
> -        <p>For this library, you can specify the maximum number of loans
> that
> -            a patron of a given category can make, regardless of the item
> type.
> -        </p>
> -        <p>If the total amount loanable for a given patron category is
> left blank,
> -           no limit applies, except possibly for a limit you define for a
> specific item type.
> -        </p>
> -    </div>
> -    <div>
> -        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
> -            <input type="hidden" name="op" value="add-branch-cat" />
> -            <input type="hidden" name="branch" value="<!-- TMPL_VAR
> NAME="branch" -->"/>
> -            <table>
> -                <tr>
> -                    <th>Patron Category</th>
> -                    <th>Total Current Checkouts Allowed</th>
> -                    <th>&nbsp;</th>
> -                </tr>
> -                <!-- TMPL_LOOP NAME="branch_cat_rule_loop" -->
> -                    <!-- TMPL_UNLESS NAME="__odd__" -->
> -                    <tr class="highlight">
> -                    <!-- TMPL_ELSE -->
> -                    <tr>
> -                    <!-- /TMPL_UNLESS -->
> -                        <td><!-- TMPL_IF NAME="default_humancategorycode"
> -->
> -                                <em>Default</em>
> -                            <!-- TMPL_ELSE -->
> -                                <!-- TMPL_VAR NAME="humancategorycode" -->
> -                            <!-- /TMPL_IF -->
> -                        </td>
> -                        <td><!-- TMPL_IF NAME="unlimited_maxissueqty" -->
> -                                Unlimited
> -                            <!-- TMPL_ELSE -->
> -                                <!-- TMPL_VAR NAME="maxissueqty" -->
> -                            <!-- /TMPL_IF -->
> -                        </td>
> -                        <td>
> -                            <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="branch"
> -->">Delete</a>
> -                        </td>
> -                    </tr>
> -                <!-- /TMPL_LOOP -->
> -                <tr>
> -                    <td>
> -                        <select name="categorycode">
> -                        <!-- TMPL_LOOP NAME="categoryloop" -->
> -                            <option value="<!-- TMPL_VAR
> NAME="categorycode" -->"><!-- TMPL_VAR NAME="description" --></option>
> -                        <!-- /TMPL_LOOP -->
> -                        </select>
> -                    </td>
> -                    <td><input name="maxissueqty" size="3" /></td>
> -                    <td><input type="submit" value="Add" class="submit"
> /></td>
> -                </tr>
> -            </table>
> -        </form>
> -    </div>
> -    <!-- /TMPL_IF -->
> -    <div class="help">
> -        <p>
> -            For this library, you can edit rules for given itemtypes,
> regardless
> -            of the patron's category.
> -        </p>
> -        <p>
> -            Currently, this means hold policies.
> -            The various policies have the following effects:
> -        </p>
> -        <ul>
> -            <li><strong>From Any Library:</strong> Patrons from any
> library may put this item on hold. <cite>(default if none is
> defined)</cite></li>
> -            <li><strong>From Home Library:</strong> Only patrons from the
> item's home library may put this book on hold.</li>
> -            <li><strong>No Holds Allowed:</strong> No patron may put this
> book on hold.</li>
> -        </ul>
> -        <p>
> -            Note that if the system preference
> -            <code>AllowHoldPolicyOverride</code> is enabled, these
> policies can
> -            be overridden by your circulation staff. Also, these policies
> are
> -            based on the patron's home branch, <em>not</em> the branch
> that
> -            the reserving staff member is from.
> -        </p>
> -    </div>
> -    <div>
> -        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
> -            <input type="hidden" name="op" value="add-branch-item" />
> -            <input type="hidden" name="branch" value="<!-- TMPL_VAR
> NAME="branch" -->"/>
> -            <table>
> -                <tr>
> -                    <th>Item Type</th>
> -                    <th>Hold Policy</th>
> -                    <th>&nbsp;</th>
> -                </tr>
> -                <!-- TMPL_LOOP NAME="branch_item_rule_loop" -->
> -                    <!-- TMPL_UNLESS NAME="__odd__" -->
> -                    <tr class="highlight">
> -                    <!-- TMPL_ELSE -->
> -                    <tr>
> -                    <!-- /TMPL_UNLESS -->
> -                        <td><!-- TMPL_IF NAME="default_humanitemtype" -->
> -                                <em>Default</em>
> -                            <!-- TMPL_ELSE -->
> -                                <!-- TMPL_VAR NAME="humanitemtype" -->
> -                            <!-- /TMPL_IF -->
> -                        </td>
> -                        <td><!-- TMPL_IF NAME="holdallowed_any" -->
> -                                From Any Library
> -                            <!-- TMPL_ELSIF NAME="holdallowed_same" -->
> -                                From Home Library
> -                            <!-- TMPL_ELSE -->
> -                                No Holds Allowed
> -                            <!-- /TMPL_IF -->
> -                        </td>
> -                        <td>
> -                            <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="branch" -->">Delete</a>
> -                        </td>
> -                    </tr>
> -                <!-- /TMPL_LOOP -->
> -                <tr>
> -                    <td>
> -                        <select name="itemtype">
> -                        <!-- TMPL_LOOP NAME="itemtypeloop" -->
> -                            <option value="<!-- TMPL_VAR NAME="itemtype"
> -->"><!-- TMPL_VAR NAME="description" --></option>
> -                        <!-- /TMPL_LOOP -->
> -                        </select>
> -                    </td>
> -                    <td>
> -                        <select name="holdallowed">
> -                            <option value="2">From Any Library</option>
> -                            <option value="1">From Home Library</option>
> -                            <option value="0">No Holds Allowed</option>
> -                        </select>
> -                    </td>
> -                    <td><input type="submit" value="Add" class="submit"
> /></td>
> -                </tr>
> -            </table>
> -        </form>
> -    </div>
>  </div>
>
>  </div>
> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
> index 20b3650..6194a99 100644
> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl
> @@ -9,6 +9,10 @@
>  <script type="text/javascript" src="<!-- TMPL_VAR name="themelang"
> -->/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
>  <script type="text/javascript">
>  //<![CDATA[
> +function Dopop(link) {
> +    var
> newin=window.open(link,'popup','width=600,height=400,resizable=1,toolbar=0,scrollbars=1,top');
> +}
> +
>  <!-- TMPL_IF NAME="UseTablesortForCirc" -->$.tablesorter.addParser({
>     id: 'articles',
>     is: function(s) {return false;  },
> @@ -23,9 +27,20 @@
>                dateFormat: 'uk',<!-- /TMPL_IF -->
>                headers: { 1: { sorter: 'articles' },5: { sorter: false
> },6:{sorter:false},7:{sorter:false},8:{sorter:false}}
>                });
> +               $("#relissuest").tablesorter({<!-- TMPL_IF
> NAME="dateformat_metric" -->
> +               dateFormat: 'uk',<!-- /TMPL_IF -->
> +               headers: { 1: { sorter: 'articles' },5: { sorter: false
> },6:{sorter:false},7:{sorter:false},8:{sorter:false}}
> +               });
> +
> +               //FIXME: Sorting does not work when there are previous
> checkouts only
> +               // (It works fine when there are only checkouts of the day,
> or both previous and today checkouts)
>                $("#issuest").bind("sortEnd",function() {
>                $("#previous").parents("tr").remove();  // 'previous
> checkouts' header chokes table sorter
>            });
> +               $("#relissuest").bind("sortEnd",function() {
> +                   $("#relprevious").parents("tr").remove();  // 'previous
> checkouts' header chokes table sorter
> +               });
> +
>                $("#holdst").tablesorter({<!-- TMPL_IF
> NAME="dateformat_metric" -->
>                dateFormat: 'uk',<!-- /TMPL_IF -->
>                        sortList: [[0,0]],
> @@ -42,14 +57,15 @@
>         <!-- /TMPL_IF -->
>
>  var allcheckboxes = $(".checkboxed");
> -       $("#renew_all").click(function(){
> -               $(allcheckboxes).checkCheckboxes(":input[name*=items]");
> -
> $(allcheckboxes).unCheckCheckboxes(":input[name*=barcodes]");
> -       });
>        $("#CheckAllitems").click(function(){
>                $(allcheckboxes).checkCheckboxes(":input[name*=items]");
>
>  $(allcheckboxes).unCheckCheckboxes(":input[name*=barcodes]"); return false;
>        });
> +//    $(":input[name*]=items").click(function(){
> +//        var itemnumber=getitemnumber($(this).attr(‘id’));
> +//        alert(getitemnumber($(this).attr(‘id’)));
> +//        $("#return_"+itemnumber).attr('checked',
> !$(this).attr('checked'));
> +//     });
>     $("#CheckNoitems").click(function(){
>                $(allcheckboxes).unCheckCheckboxes(":input[name*=items]");
> return false;
>        });
> @@ -64,12 +80,9 @@ var allcheckboxes = $(".checkboxed");
>     <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals" -->
>     <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
>     $( '#override_limit' ).click( function () {
> -        if ( this.checked ) {
> -           $( '.renewals-allowed' ).show(); $( '.renewals-disabled'
> ).hide();
> -        } else {
> -           $( '.renewals-allowed' ).hide(); $( '.renewals-disabled'
> ).show();
> -        }
> +           $( '.renewals-allowed' ).toggle();
>     } ).attr( 'checked', false );
> +    $( '.renewals-allowed' ).hide();
>     <!-- /TMPL_IF -->
>     <!-- /TMPL_IF -->
>     // Clicking the table cell checks the checkbox inside it
> @@ -108,13 +121,38 @@ var allcheckboxes = $(".checkboxed");
>         radioCheckBox($(this));
>      });
>  });
> -
> +   index = id.IndexOf("_");
> +   return id.substr(index+1);
> +}
> +function uncheck_sibling(me){
> +nodename=me.getAttribute("name");
> +if (nodename =="barcodes[]"){
> +    var Node=me.parentNode.previousSibling;
> +    while (Node.nodeName!="TD"){Node=Node.previousSibling}
> +    var Nodes=Node.childNodes;
> +    for (var i=0;i<Nodes.length;i++){
> +      if (Nodes[i].nodeName=="INPUT" &&
> Nodes[i].getAttribute("type")=="checkbox"){
> +        Nodes[i].checked=false;
> +      }
> +   }
> +
> +}else {
> +    var Node=me.parentNode.nextSibling;
> +    while (Node.nodeName!="TD"){Node=Node.nextSibling}
> +    var Nodes=Node.childNodes;
> +    for (var i=0;i<Nodes.length;i++){
> +      if (Nodes[i].nodeName=="INPUT" &&
> Nodes[i].getAttribute("type")=="checkbox"){
> +        Nodes[i].checked=false;
> +      }
> +   }
> +}
> +}
>  function validate1(date) {
>     var today = new Date();
> -    if ( date < today ) {
> -        return true;
> -     } else {
> +    if ( today < date || date.toDateString() == today.toDateString() ) {
>         return false;
> +     } else {
> +        return true;
>      }
>  };
>  function refocus(calendar) {
> @@ -190,10 +228,17 @@ function refocus(calendar) {
>  </form>
>  </div>
>
> -<!-- TMPL_IF NAME="dateexpiry" --><div class="dialog message">Patron's
> account has been renewed until <!-- TMPL_VAR NAME="dateexpiry" --></div><!--
> /TMPL_IF -->
> +<!-- TMPL_INCLUDE NAME="reserves_waiting.inc" -->
> +
> +<!-- TMPL_IF name="circnote" -->
> +    <div id="circnote" class="dialog alert">
> +       <h3>Circulation note:</h2>
> +       <!-- TMPL_VAR name="circnote" -->
> +    </div>
> +<!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="newexpiry" --><div class="dialog message">Patron's
> account has been renewed until <!-- TMPL_VAR NAME="newexpiry" --></div><!--
> /TMPL_IF -->
>  <!-- TMPL_IF NAME="NEEDSCONFIRMATION" -->
>  <div class="yui-g">
> -
>  <div id="circ_needsconfirmation" class="dialog alert">
>  <h3>Please Confirm Checkout</h3>
>
> @@ -202,10 +247,6 @@ function refocus(calendar) {
>     <li>The patron has a debt of <!-- TMPL_VAR name="DEBT" --></li>
>  <!-- /TMPL_IF -->
>
> -<!-- TMPL_IF NAME="RENEW_ISSUE" -->
> -    <li>Item is currently checked out to this patron.  Renew?</li>
> -<!-- /TMPL_IF -->
> -
>  <!-- TMPL_IF NAME="RESERVE_WAITING" -->
>     <li>Item is consigned for <!-- TMPL_VAR NAME="RESERVE_WAITING" --></li>
>  <!-- /TMPL_IF -->
> @@ -214,28 +255,45 @@ function refocus(calendar) {
>     <li>Item is on hold for <!-- TMPL_VAR NAME="RESERVED" --></li>
>  <!-- /TMPL_IF -->
>
> -<!-- TMPL_IF NAME="ISSUED_TO_ANOTHER" -->
> -    <li>Item ( <!-- TMPL_VAR NAME="getTitleMessageIteminfo" --> ) checked
> out to <!-- TMPL_VAR NAME="ISSUED_TO_ANOTHER" -->. Check in and check
> out?</li>
> -<!-- /TMPL_IF -->
> -
>  <!-- TMPL_IF NAME="TOO_MANY" -->
> -    <li>Too many checked out (already checked out / max : <!-- TMPL_VAR
> name="TOO_MANY" -->)</li>
> +    <li>Check out limit reached (already checked out / max : <!-- TMPL_VAR
> name="TOO_MANY" -->)</li>
>  <!-- /TMPL_IF -->
>
>  <!-- TMPL_IF NAME="BORRNOTSAMEBRANCH" -->
>     <li>This patrons is from a different library (<!-- TMPL_VAR
> NAME="BORRNOTSAMEBRANCH" -->)</li>
>  <!-- /TMPL_IF -->
>
> +<!-- TMPL_IF NAME="BRANCH_TRANSFER_NOT_ALLOWED" -->
> +    <li>Item should be at <!--TMPL_VAR
> Name="BRANCH_TRANSFER_NOT_ALLOWED"-->.<br /> It should not be checked out in
> this library.</li>
> +<!-- /TMPL_IF -->
> +
>  <!-- TMPL_IF NAME="PATRON_CANT" -->
> -    <li>This patron can't check out this item per library circulation
> policy</i>
> +    <li>This patron can't check out this item per library circulation
> policy</li>
> +<!-- /TMPL_IF -->
> +
> +<!-- TMPL_IF NAME="USERBLOCKEDOVERDUE" -->
> +    <li>This patron can't check out this item.  Debarred until :
> <!--TMPL_VAR Name="USERBLOCKEDOVERDUE"--> </li>
>  <!-- /TMPL_IF -->
>
>  <!-- TMPL_IF NAME="NOT_FOR_LOAN_FORCING" -->
>     <li>Item is normally not for loan.  Check out anyway?</li>
>  <!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="USERBLOCKEDOVERDUE" -->
> -    <li>Patron has <!-- TMPL_VAR NAME="USERBLOCKEDOVERDUE" --> overdue
> item(s).  Check out anyway?</li>
> +<!-- TMPL_IF NAME="DAMAGED" -->
> +    <li>Item is considered damaged (<!-- TMPL_VAR NAME="DAMAGED" -->).
> Check out anyway?</li>
>  <!-- /TMPL_IF -->
> +
> +<!-- TMPL_IF NAME="ISSUED_TO_ANOTHER" -->
> +    <li>Item ( <!-- TMPL_VAR NAME="getTitleMessageIteminfo" --> ) checked
> out to <!-- TMPL_VAR NAME="ISSUED_TO_ANOTHER" -->. Check in and check
> out?</li>
> +<!-- /TMPL_IF -->
> +
> +<!-- TMPL_IF NAME="RENEW_ISSUE" -->
> +    <li>Item is currently checked out to this patron.  Renew?</li>
> +<!-- /TMPL_IF -->
> +
> +<!-- TMPL_IF NAME="USERBLOCKEDREMAINING" -->
> +    <li>Patron cannot check-out this item : has overdue items.</li>
> +<!-- /TMPL_IF -->
> +
>  </ul>
>
>  <form method="post" action="/cgi-bin/koha/circ/circulation.pl">
> @@ -303,6 +361,10 @@ function refocus(calendar) {
>             <li>The barcode was not found <!-- TMPL_VAR NAME="barcode"
> --></li>
>         <!-- /TMPL_IF -->
>
> +        <!-- TMPL_IF NAME="LOAN_LENGTH_UNDEFINED" -->
> +            <li>No circulation rule defined for <!-- TMPL_VAR
> Name="LOAN_LENGTH_UNDEFINED"--> </li>
> +        <!-- /TMPL_IF -->
> +
>         <!-- TMPL_IF NAME="NOT_FOR_LOAN" -->
>             <li>Item not for loan</li>
>         <!-- /TMPL_IF -->
> @@ -316,15 +378,11 @@ function refocus(calendar) {
>         <!-- /TMPL_IF -->
>
>         <!-- TMPL_IF NAME="GNA" -->
> -            <li>Patron's address is in doubt</li>
> +            <li>Patron's address is in doubt<!-- TMPL_IF
> NAME="gonenoaddresscomment" -->: <!-- TMPL_VAR NAME="gonenoaddresscomment"
> --><!-- /TMPL_IF --></li>
>         <!-- /TMPL_IF -->
>
>         <!-- TMPL_IF NAME="CARD_LOST" -->
> -            <li>Patron's card is lost</li>
> -        <!-- /TMPL_IF -->
> -
> -        <!-- TMPL_IF NAME="DEBARRED" -->
> -            <li>Patron is restricted</li>
> +            <li>Patron's card is lost<!-- TMPL_IF NAME="lostcomment" -->:
> <!-- TMPL_VAR NAME="lostcomment" --><!-- /TMPL_IF --></li>
>         <!-- /TMPL_IF -->
>
>         <!-- TMPL_IF NAME="NO_MORE_RENEWALS" -->
> @@ -353,7 +411,6 @@ function refocus(calendar) {
>     <!-- /TMPL_IF -->
>
>  </div></div>
> -<!-- TMPL_ELSE -->
>  <!-- TMPL_IF NAME="soundon" -->
>  <audio src="/intranet-tmpl/prog/sound/beep.ogg" autoplay="autoplay"
> autobuffer="autobuffer"></audio>
>  <!-- /TMPL_IF -->
> @@ -429,40 +486,29 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>                <img src="<!-- TMPL_VAR Name="themelang"
> -->/lib/calendar/cal.gif" alt="Show Calendar"  border="0"
> id="CalendarDueDate" style="cursor: pointer;" />
>              <script language="JavaScript" type="text/javascript">
>                         //<![CDATA[
> -                   function validate1(date) {
> -                         var today = new Date();
> -                         if ( date < today ) {
> -                             return true;
> -                          } else {
> -                             return false;
> -                          }
> -                     };
> -                     function refocus(calendar) {
> -                        $('#barcode').focus();
> -                        calendar.hide();
> -                     };
>                                //#TODO - ADD syspref
> (AllowPostDatedCheckouts).
>                      Calendar.setup(
>                           {
>                              inputField : "duedatespec",
>                              ifFormat : "<!-- TMPL_VAR
> NAME="DHTMLcalendar_dateformat" -->",
>                              button : "CalendarDueDate",
> -//                           disableFunc : validate1,
> -//                           dateStatusFunc : validate1,
> +                             dateStatusFunc : validate1,
>                              onClose : refocus
>                            }
>                         );
>                                //]]>
>                  </script>
> -
> -          <label for="stickyduedate"> Remember for Session:</label>
> -<!-- TMPL_IF NAME="stickyduedate" -->
> -<input type="checkbox" id="stickyduedate"
> onclick="this.form.barcode.focus();" name="stickyduedate" checked="checked"
> />
> -<!-- TMPL_ELSE -->
> -<input type="checkbox" id="stickyduedate"
> onclick="this.form.barcode.focus();" name="stickyduedate" />
> +        </p><p>
> +        <label for="stickyduedate"> Remember for Session:</label>
> +        <!-- TMPL_IF NAME="stickyduedate" -->
> +            <input type="checkbox" id="stickyduedate"
> onclick="this.form.barcode.focus();" name="stickyduedate" checked="checked"
> />
> +        <!-- TMPL_ELSE -->
> +            <input type="checkbox" id="stickyduedate"
> onclick="this.form.barcode.focus();" name="stickyduedate" />
> +        <!-- /TMPL_IF -->
> +        <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;" />
> +        </p>
> +    </div>
>  <!-- /TMPL_IF -->
> -          <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;" />
> -</div><!-- /TMPL_IF -->
>           <input type="hidden" name="borrowernumber" id="borrowernumber"
> value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
>           <input type="hidden" name="branch" value="<!-- TMPL_VAR
> NAME="branch" -->" />
>           <input type="hidden" name="printer" value="<!-- TMPL_VAR
> NAME="printer" -->" />
> @@ -485,7 +531,8 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>         <div id="circmessages" class="circmessage attention">
>                <!-- /TMPL_IF -->
>
> -               <h3><!-- TMPL_IF NAME="noissues" -->Cannot Check Out!<!--
> TMPL_ELSE -->Attention:<!-- /TMPL_IF --></h3>
> +               <h3><!-- TMPL_IF NAME="noissues" -->Cannot Check Out!<!--
> TMPL_ELSE -->
> +                  <!-- TMPL_IF NAME="warning" -->Attention:<!-- /TMPL_IF
> --><!-- /TMPL_IF --></h3>
>                <ul>
>
>                        <!-- TMPL_IF NAME = "warndeparture" -->
> @@ -509,16 +556,21 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>                        <!-- /TMPL_IF -->
>
>             <!-- TMPL_IF NAME="gna" -->
> -                       <li class="blocker"><span
> class="circ-hlt">Address:</span> Patron's address in doubt</li>
> +                       <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>
>                        <!-- /TMPL_IF -->
>
>             <!-- TMPL_IF NAME="lost" -->
> -                       <li class="blocker"><span class="circ-hlt">Lost:
> </span>Patron's card is lost</li>
> +                       <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>
>                        <!-- /TMPL_IF -->
>
> -            <!-- TMPL_IF NAME="dbarred" --><li class="blocker">
> -               <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>
> -</li><!-- /TMPL_IF -->
> +            <!-- TMPL_IF NAME="userdebarred" --><li class="blocker">
> +               <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 -->
> +               <form class="inline compact" action="/cgi-bin/koha/members/
> setstatus.pl" method="post">
> +                       <input type="hidden" name="borrowernumber"
> value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
> +                       <input type="hidden" name="destination"
> value="circ" />
> +                       <input type="submit" value="Lift Debarment" />
> +               </form>
> +                       </li><!-- /TMPL_IF -->
>
>                <!-- 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>
>             <!-- /TMPL_IF -->
> @@ -552,7 +604,7 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>                    <h4>Holds waiting:</h4>
>                                <!-- TMPL_LOOP NAME="WaitingReserveLoop" -->
>                                    <ul>
> -                                       <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"-->.
> +                                       <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" -->
>                                    <!-- TMPL_IF NAME="waitingat" -->
>                                        <br /><!-- TMPL_IF
> NAME="waitinghere" --><strong class="waitinghere"><!-- TMPL_ELSE
> --><strong><!-- /TMPL_IF -->Waiting at <!-- TMPL_VAR NAME="waitingat"
> --></strong>
>                                    <!-- /TMPL_IF -->
> @@ -628,20 +680,58 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>     <input type="hidden" name="borrowernumber" value="<!-- TMPL_VAR
> NAME="borrowernumber" -->" />
>     <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="branch"
> -->" />
>         <table id="issuest">
> -    <thead><tr>
> +    <thead>
> +    <tr>
>         <th scope="col">Due date</th>
>         <th scope="col">Title</th>
>         <th scope="col">Item Type</th>
> +        <th scope="col">Branch</th>
>         <th scope="col">Checked out on</th>
> -        <th scope="col">Call no</th>
> +       <!-- TMPL_IF NAME="multiple_borrowers" --><th
> scope="col">Borrower</th><!-- /TMPL_IF -->
>         <th scope="col">Charge</th>
> -        <th scope="col">Price</th>
> +        <th scope="col">Material</th>
>         <th scope="col">Renew <p class="column-tool"><a href="#"
> id="CheckAllitems">select all</a> | <a href="#"
> id="CheckNoitems">none</a></p></th>
>         <th scope="col">Check in <p class="column-tool"><a href="#"
> id="CheckAllreturns">select all</a> | <a href="#"
> id="CheckNoreturns">none</a></p></th>
>     </tr>
> -<!-- TMPL_IF NAME="todayissues" --></thead>
> -<!-- TMPL_INCLUDE NAME="checkouts-table-footer.inc" -->
> -       <tbody>
> +</thead>
> +<tfoot>
> +               <tr>
> +            <td colspan="<!-- TMPL_IF NAME="multiple_borrowers" -->6<!--
> TMPL_ELSE -->5<!-- /TMPL_IF -->" style="text-align: right;
> font-weight:bold;">Totals:</td>
> +                       <td><!-- TMPL_VAR NAME="totaldue" --></td>
> +            <td><!-- TMPL_VAR NAME="totalprice" --></td>
> +            <td colspan="2">
> +                <p>
> +                    Renewal due date: <input type="text" size="8"
> id="newduedate" name="newduedate" value="<!-- TMPL_VAR Name="newduedate"
> -->" />
> +                    <img src="<!-- TMPL_VAR Name="themelang"
> -->/lib/calendar/cal.gif" id="newduedate_button" alt="Show Calendar" />
> + <script type="text/javascript"> //<![CDATA[
> +                               //#TODO - ADD syspref
> (AllowPostDatedCheckouts).
> +                     Calendar.setup(
> +                          {
> +                             inputField : "newduedate",
> +                             ifFormat : "<!-- TMPL_VAR
> NAME="DHTMLcalendar_dateformat" -->",
> +                             button : "newduedate_button",
> +                             dateStatusFunc : validate1,
> +                             onClose : refocus
> +                           }
> +                        );
> +                               //]]>
> +                                </script>
> +                </p>
> +                <p>
> +                    <label for="exemptfine">Forgive fines on return:
> </label><input type="checkbox" name="exemptfine" value="1" />
> +                </p>
> +                <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals"
> -->
> +                <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
> +                <p>
> +                    <label for="override_limit">Override Renewal
> Limit:</label>
> +                    <input type="checkbox" name="override_limit"
> id="override_limit" value="1" />
> +                </p>
> +                <!-- /TMPL_IF -->
> +                <!-- /TMPL_IF -->
> +            </td>
> +        </tr>
> +               </tfoot>
> +<!-- TMPL_IF NAME="todayissues" -->    <tbody>
>
>     <!-- TMPL_LOOP NAME="todayissues" -->
>     <!-- TMPL_IF NAME="__odd__" -->
> @@ -649,119 +739,95 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>     <!-- TMPL_ELSE -->
>     <tr class="highlight">
>     <!-- /TMPL_IF -->
> -        <td><!-- TMPL_VAR NAME="dd" --></td>
> +        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE
> --><td><!-- /TMPL_IF -->
> +            <!-- TMPL_VAR NAME="dd" --></td>
>         <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>
>         <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>
> -        <td><!-- TMPL_VAR NAME="checkoutdate" --></td>
> -        <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
> +       <td><!-- TMPL_VAR NAME="branchdisplay" -->
> +        <!--TMPL_IF Name="itemcallnumber"-->(<!-- TMPL_VAR
> NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
> +        <td><!-- TMPL_VAR NAME="displaydate" --></td>
> +       <!-- TMPL_IF NAME="multiple_borrowers" --><td><!-- TMPL_VAR
> NAME="borrowername" --></td><!-- /TMPL_IF -->
>             <td><!-- TMPL_VAR NAME="charge" --></td>
> -            <td><!-- TMPL_VAR NAME="replacementprice" --></td>
> -      <!-- TMPL_IF NAME="renew_failed" -->
> -            <td class="problem">Renewal Failed</td>
> -      <!-- TMPL_ELSE -->
> -        <td><span style="padding: 0 1em;"><!-- TMPL_IF NAME="renewals"
> --><!-- TMPL_VAR NAME="renewals" --><!-- TMPL_ELSE -->0<!-- /TMPL_IF
> --></span>
> -        <!-- TMPL_IF NAME="can_renew" -->
> -        <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR
> NAME="itemnumber" -->" checked="checked" style="display: none;" />
> -        <!-- TMPL_IF NAME="od" -->
> -            <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
> -        <!-- TMPL_ELSE -->
> -            <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> -        <!-- /TMPL_IF -->
> -        <!-- TMPL_ELSE -->
> -            <!-- TMPL_IF NAME="can_confirm" --><span
> class="renewals-allowed" style="display: none">
> -                <input type="checkbox" name="all_items[]" value="<!--
> TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
> -                <!-- TMPL_IF NAME="od" -->
> -                    <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
> -                <!-- TMPL_ELSE -->
> -                    <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> -                <!-- /TMPL_IF -->
> +            <td><!-- TMPL_VAR NAME="materials" --></td>
> +            <td><span style="padding: 0 1em;">
> +            <!-- TMPL_IF Name="renew_error_too_many"--><span
> class="problem"><!-- /TMPL_IF -->
> +            <!-- TMPL_VAR NAME="renewals" -->/<!-- TMPL_VAR
> NAME="renewalsallowed" -->
> +            <!-- TMPL_IF NAME="renew_error_too_many"--></span><!--
> /TMPL_IF -->
>                 </span>
> -                <span class="renewals-disabled">
> +        <!-- TMPL_UNLESS NAME="can_renew" -->
> +            <span class="renewals-allowed" style="display: none">
> +        <!-- /TMPL_UNLESS  -->
> +        <input type="checkbox" id="renew_<!--TMPL_VAR
> NAME="itemnumber"-->" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber"
> -->" />
> +        <!-- TMPL_UNLESS NAME="can_renew" -->
> +            </span>
> +        <!-- /TMPL_UNLESS  -->
> +
> +            <!-- TMPL_IF NAME="renew_error"-->
> +            <br/>
> +            <span class="renewals-disabled problem">
> +            <!-- TMPL_IF NAME="renew_error_on_reserve" --> On Hold
> <!-- /TMPL_IF -->
> +            <!-- TMPL_IF NAME="renew_error_overdue"    --> Overdue
> <!-- /TMPL_IF -->
> +            <!-- TMPL_IF NAME="renew_error_too_many"   --> Not Renewable
> <!-- /TMPL_IF -->
> +            </span>
>             <!-- /TMPL_IF -->
> -               <!-- TMPL_IF NAME="renew_error_on_reserve" -->
> -                       On Hold
> -               <!-- /TMPL_IF -->
> -                <!-- TMPL_IF NAME="renew_error_too_many" -->
> -                       Not Renewable
> -                <!-- /TMPL_IF -->
> -            <!-- TMPL_IF NAME="can_confirm" -->
> -                </span>
> -            <!-- /TMPL_IF -->
> -        <!-- /TMPL_IF -->
>         </td>
> -        <!-- /TMPL_IF -->
>   <!-- TMPL_IF NAME="return_failed" -->
>             <td class="problem">Checkin Failed</td>
>       <!--TMPL_ELSE-->
> -            <td><input type="checkbox" class="radio" name="barcodes[]"
>  value="<!-- TMPL_VAR NAME="barcode" -->" />
> -                <input type="checkbox" name="all_barcodes[]" value="<!--
> TMPL_VAR NAME="barcode" -->" checked="checked" style="display: none;" />
> +            <td style="text-align:center;"><input type="checkbox"
> id="return_<!--TMPL_VAR NAME="itemnumber"-->" name="barcodes[]"  value="<!--
> TMPL_VAR NAME="barcode" -->" />
> +                <!-- 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 -->
>             </td>
>       <!-- /TMPL_IF -->
>     </tr>
>     <!-- /TMPL_LOOP --> <!-- /loop todayissues -->
>     <!-- /if todayissues --><!-- /TMPL_IF -->
>  <!-- TMPL_IF NAME="previssues" -->
> -<!-- TMPL_IF NAME="todayissues" --><tr><th colspan="10"><a name="previous"
> id="previous"></a>Previous checkouts</th></tr><!-- TMPL_ELSE -->
> -<tr><th class="{sorter: false}" colspan="10"><a name="previous"
> id="previous"></a>Previous checkouts</th></tr></thead>
> -<!-- TMPL_INCLUDE NAME="checkouts-table-footer.inc" -->
> -       <tbody>
> -<!-- /TMPL_IF -->
> +<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>
>     <!-- TMPL_LOOP NAME="previssues" -->
>     <!-- TMPL_IF NAME="__odd__" -->
>         <tr>
>     <!-- TMPL_ELSE -->
>         <tr class="highlight">
>     <!-- /TMPL_IF -->
> -        <!-- TMPL_IF NAME="od" --><td class="od"><!-- TMPL_ELSE
> --><td><!-- /TMPL_IF -->
> +        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE
> --><td><!-- /TMPL_IF -->
>         <!-- TMPL_VAR NAME="dd" -->
>         </td>
>         <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>
>         <td>
>             <!-- TMPL_VAR NAME="itemtype" -->
>         </td>
> +       <td><!-- TMPL_VAR NAME="branchdisplay" -->
> +        <!--TMPL_IF NAME="itemcallnumber"-->(<!-- TMPL_VAR
> NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
>         <td><!-- TMPL_VAR NAME="displaydate" --></td>
> -        <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
> +       <!-- TMPL_IF NAME="multiple_borrowers" --><td><!-- TMPL_VAR
> NAME="borrowername" --></td><!-- /TMPL_IF -->
>         <td><!-- TMPL_VAR NAME="charge" --></td>
> -        <td><!-- TMPL_VAR NAME="replacementprice" --></td>
> -      <!-- TMPL_IF NAME="renew_failed" -->
> -            <td class="problem">Renewal Failed</td>
> -      <!-- TMPL_ELSE -->
> -        <td><span style="padding: 0 1em;"><!-- TMPL_IF NAME="renewals"
> --><!-- TMPL_VAR NAME="renewals" --><!-- TMPL_ELSE -->0<!-- /TMPL_IF
> --></span>
> -        <!-- TMPL_IF NAME="can_renew" -->
> -        <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR
> NAME="itemnumber" -->" checked="checked" style="display: none;" />
> -        <!-- TMPL_IF NAME="od" -->
> -            <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
> -        <!-- TMPL_ELSE -->
> -            <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> -        <!-- /TMPL_IF -->
> -        <!-- TMPL_ELSE -->
> -            <!-- TMPL_IF NAME="can_confirm" --><span
> class="renewals-allowed" style="display: none">
> -                <input type="checkbox" name="all_items[]" value="<!--
> TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
> -                <!-- TMPL_IF NAME="od" -->
> -                    <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
> -                <!-- TMPL_ELSE -->
> -                    <input type="checkbox" class="radio" name="items[]"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> -                <!-- /TMPL_IF -->
> -                </span>
> -                <span class="renewals-disabled">
> -            <!-- /TMPL_IF -->
> -               <!-- TMPL_IF NAME="renew_error_on_reserve" -->
> -                       On Hold
> -               <!-- /TMPL_IF -->
> -                <!-- TMPL_IF NAME="renew_error_too_many" -->
> -                       Not Renewable
> -                <!-- /TMPL_IF -->
> -            <!-- TMPL_IF NAME="can_confirm" -->
> -                </span>
> +        <td><!-- TMPL_VAR NAME="materials" --></td>
> +        <td style="text-align : center;"><span style="padding: 0 1em;">
> +            <!-- TMPL_IF Name="renew_error_too_many"--><span
> class="problem"><!-- /TMPL_IF -->
> +            <!-- TMPL_VAR NAME="renewals" -->/<!-- TMPL_VAR
> NAME="renewalsallowed" -->
> +            <!-- TMPL_IF Name="renew_error_too_many"--></span><!--
> /TMPL_IF -->
> +            </span>
> +        <!-- TMPL_UNLESS NAME="can_renew" -->
> +            <span class="renewals-allowed" style="display: none">
> +        <!-- /TMPL_UNLESS  -->
> +        <input type="checkbox" id="renew_<!--TMPL_VAR
> NAME="itemnumber"-->" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber"
> -->" />
> +        <!-- TMPL_UNLESS NAME="can_renew" -->
> +            </span>
> +        <!-- /TMPL_UNLESS  -->
> +            <!-- TMPL_IF NAME="renew_error"-->
> +            <br/>
> +            <span class="renewals-disabled problem">
> +            <!-- TMPL_IF NAME="renew_error_on_reserve" --> On Hold
> <!-- /TMPL_IF -->
> +            <!-- TMPL_IF NAME="renew_error_overdue"    --> Overdue
> <!-- /TMPL_IF -->
> +            <!-- TMPL_IF NAME="renew_error_too_many"   --> Not Renewable
> <!-- /TMPL_IF -->
> +            </span>
>             <!-- /TMPL_IF -->
> -        <!-- /TMPL_IF -->
>         </td>
> -        <!-- /TMPL_IF -->
>                  <!-- TMPL_IF NAME="return_failed" -->
>             <td class="problem">Checkin Failed</td>
> -        <!--TMPL_ELSE-->
> -            <td><input type="checkbox" class="radio" name="barcodes[]"
>  value="<!-- TMPL_VAR NAME="barcode" -->" />
> -                <input type="checkbox" name="all_barcodes[]" value="<!--
> TMPL_VAR NAME="barcode" -->" checked="checked" style="display: none;" />
> +      <!--TMPL_ELSE-->
> +            <td style="text-align : center;"><input type="checkbox"
> id="return_<!--TMPL_VAR NAME="itemnumber"-->" name="barcodes[]"  value="<!--
> TMPL_VAR NAME="barcode" -->" onclick="uncheck_sibling(this);" />
> +                <!-- 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 -->
>             </td>
>       <!-- /TMPL_IF -->
>     </tr>
> @@ -771,20 +837,81 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>     </table>
>     <!--TMPL_IF NAME="issuecount"-->
>     <fieldset class="action">
> -        <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals" -->
> -        <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
> -        <label for="override_limit">Override Renewal Limit:</label>
> -        <input type="checkbox" name="override_limit" id="override_limit"
> value="1" />
> -        <!-- /TMPL_IF -->
> -        <!-- /TMPL_IF -->
>         <input type="submit" name="renew_checked" value="Renew or Return
> checked items" />
> -        <input type="submit" id="renew_all" name="renew_all" value="Renew
> all" />
>         </fieldset>
>     <!-- /TMPL_IF -->
>  </form>
>  <!-- TMPL_ELSE -->
>  <p>Patron has nothing checked out.</p>
>  <!-- /TMPL_IF -->
> +
> +
> +<!-- TMPL_IF NAME="displayrelissues" -->
> +<h2>Relatives issues</h2>
> +    <table id="relissuest">
> +    <thead>
> +    <tr>
> +        <th scope="col">Due date</th>
> +        <th scope="col">Title</th>
> +        <th scope="col">Item Type</th>
> +        <th scope="col">Branch</th>
> +        <th scope="col">Checked out on</th>
> +        <th scope="col">Charge</th>
> +       <th scope="col">Borrower</th>
> +        <th scope="col">Material</th>
> +    </tr>
> +    </thead>
> +<!-- TMPL_IF NAME="relissues" -->      <tbody>
> +
> +    <!-- TMPL_LOOP NAME="relissues" -->
> +    <!-- TMPL_IF NAME="__odd__" -->
> +    <tr>
> +    <!-- TMPL_ELSE -->
> +    <tr class="highlight">
> +    <!-- /TMPL_IF -->
> +        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE
> --><td><!-- /TMPL_IF -->
> +            <!-- TMPL_VAR NAME="dd" --></td>
> +        <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>
> +        <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>
> +       <td><!-- TMPL_VAR NAME="branchdisplay" -->
> +        <!--TMPL_IF Name="itemcallnumber"-->(<!-- TMPL_VAR
> NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
> +        <td><!-- TMPL_VAR NAME="displaydate" --></td>
> +            <td><!-- TMPL_VAR NAME="charge" --></td>
> +            <td><a href="/cgi-bin/koha/members/
> moremember.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->"><!--
> TMPL_VAR NAME="borrowername" --></a></td>
> +            <td><!-- TMPL_VAR NAME="materials" --></td>
> +    </tr>
> +    <!-- /TMPL_LOOP --> <!-- /loop todayissues -->
> +    <!-- /if todayissues --><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="relprevissues" -->
> +<tr><th class="{sorter: false}" colspan="10"><a name="relprevious"
> id="relprevious"></a>Previous checkouts</th></tr>
> +    <!-- TMPL_LOOP NAME="relprevissues" -->
> +    <!-- TMPL_IF NAME="__odd__" -->
> +        <tr>
> +    <!-- TMPL_ELSE -->
> +        <tr class="highlight">
> +    <!-- /TMPL_IF -->
> +        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE
> --><td><!-- /TMPL_IF -->
> +        <!-- TMPL_VAR NAME="dd" -->
> +        </td>
> +        <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>
> +        <td>
> +            <!-- TMPL_VAR NAME="itemtype" -->
> +        </td>
> +       <td><!-- TMPL_VAR NAME="branchdisplay" -->
> +        <!--TMPL_IF NAME="itemcallnumber"-->(<!-- TMPL_VAR
> NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
> +        <td><!-- TMPL_VAR NAME="displaydate" --></td>
> +       <!-- TMPL_IF NAME="multiple_borrowers" --><td><!-- TMPL_VAR
> NAME="borrowername" --></td><!-- /TMPL_IF -->
> +        <td><!-- TMPL_VAR NAME="charge" --></td>
> +       <td><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=<!--
> TMPL_VAR NAME="borrowernumber" -->"><!-- TMPL_VAR NAME="borrowername"
> --></a></td>
> +        <td><!-- TMPL_VAR NAME="materials" --></td>
> +    </tr>
> +    <!-- /loop previssues --><!-- /TMPL_LOOP -->
> +<!--/if previssues --><!-- /TMPL_IF -->
> +      </tbody>
> +    </table>
> +</form>
> +<!-- /TMPL_IF --><!-- end displayrelissues -->
> +
>  </div>
>
>
> @@ -808,7 +935,7 @@ No patron matched <span class="ex"><!-- TMPL_VAR
> name="message" --></span>
>                     <td><a href="/cgi-bin/koha/reserve/
> request.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber"
> -->"><strong><!-- TMPL_VAR NAME="title" escape="html" --></strong></a><!--
> TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF
> --></td>
>                     <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
>                                        <td><em><!-- TMPL_IF
> name="barcodereserv" -->Item <!-- TMPL_VAR NAME="barcodereserv" -->
> -                        <!-- /TMPL_IF --><!-- TMPL_IF name="waiting" -->
> <strong>waiting at <!-- TMPL_VAR NAME="waitingat" --></strong>
> +                        <!-- /TMPL_IF --><!-- TMPL_IF name="waiting" -->
> <strong>waiting at <!-- TMPL_VAR NAME="waitingat" --> <!-- TMPL_IF
> name="formattedwaitingdate" --> until <!-- TMPL_VAR
> NAME="formattedwaitingdate" --><!--/TMPL_IF--></strong>
>                         <!-- /TMPL_IF -->
>                         <!-- TMPL_IF name="transfered" --> <strong>in
> transit</strong> from
>                         <!-- TMPL_VAR NAME="frombranch" --> since <!--
> TMPL_VAR NAME="datesent" -->
> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tmpl
> index ba8d117..e1896a5 100644
> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tmpl
> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/returns.tmpl
> @@ -1,6 +1,9 @@
>  <!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
>  <title>Koha &rsaquo; Circulation &rsaquo; Check In <!-- TMPL_VAR
> Name="title" escape="html" --></title>
>  <!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
> +<style type="text/css">
> +    background-color: red;
> +</style>
>  <script type="text/javascript">
>  //<![CDATA[
>  function Dopop(link) {
> @@ -46,7 +49,6 @@ function Dopop(link) {
>  <!-- TMPL_INCLUDE NAME="checkin-search.inc" -->
>
>  <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a>
> &rsaquo; <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a>
> &rsaquo; Check In</div>
> -
>  <div id="doc" class="yui-t7">
>
>    <div id="bd">
> @@ -54,14 +56,26 @@ function Dopop(link) {
>
>  <div class="yui-g">
>
> -<!-- TMPL_IF Name="collectionItemNeedsTransferred" -->
> -       <div class="dialog message">This item is part of a Rotating
> Collection and needs to be Transferred to <!-- TMPL_VAR
> NAME="collectionBranch" --></div>
> +<!-- TMPL_IF name="circnote" -->
> +    <div id="circnote" class="dialog alert">
> +        <h3>Circulation note:</h2>
> +        <!-- TMPL_VAR name="circnote" -->
> +    </div>
>  <!-- /TMPL_IF -->
>
>  <!-- TMPL_IF NAME="wrongbranch" -->
> -<div class="dialog alert"><h3>Cannot Check In</h3><p>This item must be
> checked in at its home library. <strong>NOT CHECKED IN</strong></p>
> +<div class="dialog alert"><h3>Cannot Check In</h3><p>This item must be
> checked in at its home library: <!-- TMPL_VAR Name="rightbranch" -->.
> <strong>NOT CHECKED IN</strong></p>
> +            <form method="post" action="returns.pl" class="confirm">
> +
> +                <input type="hidden" name="barcode" value="<!-- TMPL_VAR
> Name="barcode" -->" />
> +                <input type="hidden" name="exemptfine" value="<!--
> TMPL_VAR Name="exemptfine" -->" />
> +                <input type="hidden" name="dropboxmode" value="<!--
> TMPL_VAR Name="dropboxmode" -->" />
> +                               <input type="submit" name="override"
> value="Check-In" class="submit" />
> +                               <input type="submit" name="cancel"
> value="Cancel" class="submit" />
> +               </form>
>  </div>
>  <!-- /TMPL_IF -->
> +
>  <!-- case of a mistake in transfer loop -->
>  <!-- TMPL_IF Name="WrongTransfer" --><div class="dialog message"><!--
> WrongTransfer --><h3>Please return <a href="/cgi-bin/koha/catalogue/
> detail.pl?type=intra&amp;biblionumber=<!-- TMPL_VAR
> NAME="itembiblionumber" -->"><!-- TMPL_VAR Name="title" escape="html"
> --></a> to <!-- TMPL_VAR Name="TransferWaitingAt" --></h3>
>  <!-- TMPL_IF Name="wborcnum"--><h5>Hold for:</h5>
> @@ -89,11 +103,6 @@ function Dopop(link) {
>  <!-- case of a reservation found, and display info -->
>     <!-- TMPL_IF Name="waiting" -->
>        <!-- waiting -->
> -
> -<!-- TMPL_IF NAME="soundon" -->
> -<audio src="/intranet-tmpl/prog/sound/ending.ogg" autoplay="autoplay"
> autobuffer="autobuffer"></audio>
> -<!-- /TMPL_IF -->
> -
>  <div class="dialog message">
>         <h3>Hold Found (item is already waiting):  <a
> href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR
> NAME="itembiblionumber" -->"><!-- TMPL_VAR Name="title" escape="html"
> --></a></h3>
>         <!-- TMPL_IF NAME="reservenotes" --><h4>Notes: <!-- TMPL_VAR
> Name="reservenotes" --></h4><!-- /TMPL_IF -->
> @@ -105,8 +114,9 @@ function Dopop(link) {
>             <!-- TMPL_VAR Name="borcity" --> <!-- TMPL_VAR NAME="borzip"
> --></li>
>            <!-- TMPL_IF NAME="borphone" --><li> <!-- TMPL_VAR
> Name="borphone" --></li><!-- /TMPL_IF -->
>                   <!-- TMPL_IF NAME="boremail" --><li><a id="boremail"
> href="mailto:<!-- TMPL_VAR NAME="boremail" -->"><!-- TMPL_VAR
> NAME="boremail" --></a></li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is
> RESTRICTED</li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt</li><!-- /TMPL_IF --></ul>
> +<!-- TMPL_IF NAME="lost" --><li class="error">Patron's card is lost <!--
> TMPL_IF Name="lostcomment" -->(<!-- TMPL_VAR NAME="lostcomment" -->)<!--
> /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is RESTRICTED
> <!-- TMPL_IF Name="debarredcomment" -->(<!-- TMPL_VAR NAME="debarredcomment"
> -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt<!-- TMPL_IF Name="gonenoaddresscomment" -->(<!-- TMPL_VAR
> NAME="gonenoaddresscomment" -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF --></ul>
>                <!-- TMPL_IF name="transfertodo" -->
>             <h4><strong>Transfer to:</strong> <!-- TMPL_VAR
> Name="destbranchname" --></h4>
>                <!-- TMPL_ELSE -->
> @@ -127,8 +137,10 @@ function Dopop(link) {
>                 <input type="hidden" name="diffBranch" value="<!-- TMPL_VAR
> Name="destbranch" -->" />
>                 <input type="hidden" name="exemptfine" value="<!-- TMPL_VAR
> Name="exemptfine" -->" />
>                 <input type="hidden" name="dropboxmode" value="<!--
> TMPL_VAR Name="dropboxmode" -->" />
> +               <input type="hidden" name="reservenumber" value="<!--
> TMPL_VAR Name="reservenumber" -->" />
>                 </form>
>        </div>
> +    <!-- /waiting -->
>     <!-- /TMPL_IF -->
>
>     <!-- TMPL_IF Name="diffbranch" -->
> @@ -143,8 +155,9 @@ function Dopop(link) {
>                                                <!-- TMPL_VAR Name="borcity"
> -->  <!-- TMPL_VAR NAME="borzip" --></li>
>                         <!-- TMPL_IF NAME="borphone" --><li><!-- TMPL_VAR
> Name="borphone" --></li><!-- /TMPL_IF -->
>                         <!-- TMPL_IF NAME="boremail" --><li><!-- TMPL_IF
> name="transfertodo" --><!-- TMPL_VAR NAME="boremail" --><!-- TMPL_ELSE --><a
> id="boremail" href="mailto:<!-- TMPL_VAR NAME="boremail" -->"><!--
> TMPL_VAR NAME="boremail" --></a><!-- /TMPL_IF --></li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is
> RESTRICTED</li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt</li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="lost" --><li class="error">Patron's card is lost <!--
> TMPL_IF Name="lostcomment" -->(<!-- TMPL_VAR NAME="lostcomment" -->)<!--
> /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is RESTRICTED
> <!-- TMPL_IF Name="debarredcomment" -->(<!-- TMPL_VAR NAME="debarredcomment"
> -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt<!-- TMPL_IF Name="gonenoaddresscomment" -->(<!-- TMPL_VAR
> NAME="gonenoaddresscomment" -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF --></ul>
>                     </ul>
>                <!-- TMPL_IF name="transfertodo" -->
>             <h4><strong>Transfer to:</strong> <!-- TMPL_VAR
> Name="destbranchname" --></h4>
> @@ -171,7 +184,7 @@ function Dopop(link) {
>     <!-- TMPL_IF Name="transfer" -->
>     <!-- transfer: item with no reservation, must be returned to its
> homebranch -->
>        <div class="dialog message">
> -         <h3>Please return <a href="/cgi-bin/koha/catalogue/
> detail.pl?type=intra&amp;biblionumber=<!-- TMPL_VAR
> NAME="itembiblionumber" -->"><!-- TMPL_VAR NAME="title" escape="html"
> DEFAULT="item" --></a> to <!-- TMPL_VAR NAME="homebranchname"
> --></h3></div><!-- /TMPL_IF -->
> +         <h3>Please return <a href="/cgi-bin/koha/catalogue/
> detail.pl?type=intra&amp;biblionumber=<!-- TMPL_VAR
> NAME="itembiblionumber" -->"><!-- TMPL_VAR NAME="title" escape="html"
> DEFAULT="item" --></a> to <!-- TMPL_VAR NAME="homebranch"
> DEFAULT="homebranch" --></h3></div><!-- /TMPL_IF -->
>
>     <!-- TMPL_IF Name="needstransfer" -->
>        <!-- needstransfer -->
> @@ -219,11 +232,6 @@ function Dopop(link) {
>     <!-- case of simple return no issue or transfer but with a reservation
>  -->
>     <!-- TMPL_IF Name="reserved" -->
>        <!--  reserved  -->
> -
> -<!-- TMPL_IF NAME="soundon" -->
> -<audio src="/intranet-tmpl/prog/sound/opening.ogg" autoplay="autoplay"
> autobuffer="autobuffer"></audio>
> -<!-- /TMPL_IF -->
> -
>        <div class="dialog message">
>          <h3>Hold Found: <a href="/cgi-bin/koha/catalogue/
> detail.pl?biblionumber=<!-- TMPL_VAR NAME="itembiblionumber" -->"><!--
> TMPL_VAR Name="title" escape="html" --></a></h3>
>         <!-- TMPL_IF NAME="reservenotes" --><h4>Notes: <!-- TMPL_VAR
> Name="reservenotes" --></h4><!-- /TMPL_IF -->
> @@ -237,8 +245,9 @@ function Dopop(link) {
>                        <!-- TMPL_VAR Name="borcity" --> <!-- TMPL_VAR
> NAME="borzip" --></li>
>             <!-- TMPL_IF NAME="borphone" --><li><!-- TMPL_VAR
> Name="borphone" --></li><!-- /TMPL_IF -->
>             <!-- TMPL_IF NAME="boremail" --><li><!-- TMPL_IF
> name="transfertodo" --><!-- TMPL_VAR NAME="boremail" --><!-- TMPL_ELSE --><a
> id="boremail" href="mailto:<!-- TMPL_VAR NAME="boremail" -->"><!--
> TMPL_VAR NAME="boremail" --></a><!-- /TMPL_IF --></li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is
> RESTRICTED</li><!-- /TMPL_IF -->
> -<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt</li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="lost" --><li class="error">Patron's card is lost <!--
> TMPL_IF Name="lostcomment" -->(<!-- TMPL_VAR NAME="lostcomment" -->)<!--
> /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="debarred" --><li class="error">Patron is RESTRICTED
> <!-- TMPL_IF Name="debarredcomment" -->(<!-- TMPL_VAR NAME="debarredcomment"
> -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF -->
> +<!-- TMPL_IF NAME="gonenoaddress" --><li class="error">Patron's address is
> in doubt<!-- TMPL_IF Name="gonenoaddresscomment" -->(<!-- TMPL_VAR
> NAME="gonenoaddresscomment" -->)<!-- /TMPL_IF --></li><!-- /TMPL_IF --></ul>
>         </ul>
>         <!-- TMPL_IF name="transfertodo" -->
>             <h4><strong>Transfer to:</strong> <!-- TMPL_VAR
> Name="destbranchname" --></h4>
> @@ -264,13 +273,16 @@ function Dopop(link) {
>             <input type="hidden" name="diffBranch" value="<!-- TMPL_VAR
> Name="destbranch" -->" />
>             <input type="hidden" name="exemptfine" value="<!-- TMPL_VAR
> Name="exemptfine" -->" />
>             <input type="hidden" name="dropboxmode" value="<!-- TMPL_VAR
> Name="dropboxmode" -->" />
> +           <input type="hidden" name="reservenumber" value="<!-- TMPL_VAR
> Name="reservenumber" -->" />
>         </form>
>        </div>
> +       <!--  /reserved  -->
>     <!-- /TMPL_IF -->
> -<!-- TMPL_ELSE -->
> +<!--/found-->
> +<!-- /TMPL_IF -->
>
>  <!-- TMPL_IF NAME="errmsgloop" -->
> -    <div class="dialog alert">
> +    <div class="dialog message">
>         <!-- TMPL_LOOP Name="errmsgloop" -->
>                     <!-- TMPL_IF Name="badbarcode" -->
>                         <p class="problem">No Item with barcode: <!--
> TMPL_VAR Name="msg" --></p>
> @@ -284,18 +296,22 @@ function Dopop(link) {
>                     <!-- TMPL_IF Name="waslost" -->
>                         <p class="problem">Item was lost, now found.</p>
>                     <!-- /TMPL_IF -->
> +                    <!-- TMPL_IF Name="havefines" -->
> +                        <p class="problem"><!-- TMPL_VAR NAME="finename"
> --> (<!-- TMPL_VAR NAME="finecardnumber" -->) has an outstanding fine of
> <!-- TMPL_VAR NAME="havefines" --> for books returned late.</p>
> +                    <!-- /TMPL_IF -->
>                     <!-- TMPL_IF Name="withdrawn" -->
>                         <p class="problem">Item is withdrawn.</p>
>                     <!-- /TMPL_IF -->
> +                    <!-- TMPL_IF Name="notforloan" -->
> +                        <p class="problem">Item was not for loan: <!--
> TMPL_VAR NAME="notforloan" -->.</p>
> +                    <!-- /TMPL_IF -->
> +                    <!-- TMPL_IF Name="damaged" -->
> +                        <p class="problem">Item is considered damaged
> (<!-- TMPL_VAR NAME="damaged" -->).</p>
> +                    <!-- /TMPL_IF -->
> +                    <!-- TMPL_IF Name="debarred" -->
> +                        <p class="problem"><a href="/cgi-bin/koha/circ/
> circulation.pl?borrowernumber=<!-- TMPL_VAR NAME="debarborrowernumber"
> -->"><!-- TMPL_VAR NAME="debarname" -->(<!-- TMPL_VAR NAME="debarcardnumber"
> -->)</a> is now debarred until <!-- TMPL_VAR NAME="debarred" --> <!--
> TMPL_IF Name="debarredcomment"-->(<!-- TMPL_VAR NAME="debarredcomment"
> -->)<!-- /TMPL_IF -->.</p>
> +                    <!-- /TMPL_IF -->
>             <!-- /TMPL_LOOP -->
> -<!-- TMPL_IF NAME="soundon" -->
> -<audio src="/intranet-tmpl/prog/sound/critical.ogg" autoplay="autoplay"
> autobuffer="autobuffer"></audio>
> -<!-- /TMPL_IF -->
> -        <!-- TMPL_ELSE -->
> -<!-- TMPL_IF NAME="soundon" -->
> -<audio src="/intranet-tmpl/prog/sound/beep.ogg" autoplay="autoplay"
> autobuffer="autobuffer"></audio>
> -<!-- /TMPL_IF -->
> -        <!-- /TMPL_IF -->
>     </div>
>  <!-- /TMPL_IF -->
>
> @@ -357,30 +373,53 @@ function Dopop(link) {
>         </div>
>     </form>
>  </div>
> +<!-- TMPL_IF Name="flagloop" -->
> +<div class="yui-g dialog message">
> +
> +                <a href="/cgi-bin/koha/members/
> moremember.pl?borrowernumber=<!-- TMPL_VAR Name="riborrowernumber"
> -->"><!-- TMPL_VAR Name="riborsurname" -->, <!-- TMPL_VAR Name="ribortitle"
> --> <!-- TMPL_VAR Name="riborfirstname" --></a> (<!-- TMPL_VAR
> Name="riborcnum" -->)
> +            <!-- TMPL_IF NAME="flagloop"-->
> +               <ul>
> +                   <!-- TMPL_LOOP Name="flagloop" -->
> +                       <!-- TMPL_IF NAME="gonenoaddress" -->
> +                           <li>Patron's address is in doubt<!-- TMPL_IF
> NAME="gonenoaddresscomment" -->: <!-- TMPL_VAR NAME="gonenoaddresscomment"
> --><!-- /TMPL_IF --></li>
> +                       <!-- /TMPL_IF -->
>
> -<!-- TMPL_IF Name="returned" -->
> -<div class="yui-g">    <table>
> -        <tr><th>Item Information</th><th>Patron Information</th></tr>
> -        <tr>
> -            <td><!-- TMPL_VAR Name="title" escape="html" --></td>
> -            <td>
> +                       <!-- TMPL_IF NAME="lost" -->
> +                           <li>Patron's card is lost<!-- TMPL_IF
> NAME="lostcomment" -->: <!-- TMPL_VAR NAME="lostcomment" --><!-- /TMPL_IF
> --></li>
> +                       <!-- /TMPL_IF -->
>
> -                <a href="/cgi-bin/koha/members/
> moremember.pl?borrowernumber=<!-- TMPL_VAR Name="riborrowernumber"
> -->"><!-- TMPL_VAR Name="riborsurname" -->, <!-- TMPL_VAR Name="ribortitle"
> --> <!-- TMPL_VAR Name="riborfirstname" --></a> (<!-- TMPL_VAR
> Name="riborcnum" -->)
> -                <!-- TMPL_IF Name="flagset" -->
> -                (<!-- TMPL_LOOP Name="flagloop" -->
> -                <!-- TMPL_VAR Name="flag" -->
> -               <!-- TMPL_IF NAME="charges" --> of <!-- TMPL_VAR
> NAME="chargeamount" --> <!-- /TMPL_IF -->
> -               ,
> -                <!-- /TMPL_LOOP -->)<!-- /TMPL_IF -->
> -            </td>
> -        </tr>
> -    </table>
> +                       <!-- TMPL_IF NAME="debarred" -->
> +                           <li>Patron is restricted <!--TMPL_IF
> NAME="dateend"-->until <!--TMPL_VAR Name="dateend"--><!--/TMPL_IF--><!--
> TMPL_IF NAME="debarredcomment" -->: <!-- TMPL_VAR NAME="debarredcomment"
> --><!-- /TMPL_IF --></li>
> +                       <!-- /TMPL_IF -->
> +
> +                       <!-- TMPL_IF Name="waiting"-->
> +                           <li><div id="holdswaiting" class="circmessage">
> +                               <h4>Holds waiting:</h4>
> +                                   <!-- TMPL_LOOP NAME="itemloop" -->
> +                                       <ul>
> +                                           <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"--> available since <!-- TMPL_VAR NAME="waitingdate" -->
> until <!-- TMPL_VAR NAME="maxpickupdate" -->.
> +                                           <!-- TMPL_IF NAME="brname" -->
> +                                               <br /><!-- TMPL_IF
> NAME="waitinghere" --><strong class="waitinghere"><!-- TMPL_ELSE
> --><strong><!-- /TMPL_IF -->Waiting at <!-- TMPL_VAR NAME="brname"
> --></strong>
> +                                           <!-- /TMPL_IF -->
> +                                           </li>
> +                                       </ul>
> +                                   <!-- /TMPL_LOOP -->
> +                           </div></li>
> +                       <!-- /If waiting --><!-- /TMPL_IF -->
> +
> +                       <!-- TMPL_IF Name="flag"-->
> +                           <li><!-- TMPL_VAR Name="flag" --> <!-- TMPL_IF
> NAME="charges" --> of <!-- TMPL_VAR NAME="chargeamount" --> <!-- /TMPL_IF
> --> </li>
> +                       <!-- /TMPL_IF -->
> +                   <!-- /TMPL_LOOP -->
> +               </ul>
> +            <!-- /TMPL_IF -->
> +</div>
>  <!-- /TMPL_IF -->
>  <!-- TMPL_IF Name="riloop" -->
>     <h2>Checked-In items</h2>
>     <table>
> -       <tr><th>Due Date</th><th>Title</th>     <th>Author</th>
> <th>Barcode</th><th>Type</th>   <th>Patron</th><th>Note</th></tr>
> -
> +       <tr><th>Due Date</th><th>Title and Author</th>  <th>Barcode
> (Type)</th><th>Home Branch</th><th>Holding
> Branch</th><th>Location</th><th>Callnumber</th><th>Patron</th><th>Note</th></tr>
> +
>         <!-- TMPL_LOOP Name="riloop" -->
>             <tr>
>             <td><!-- TMPL_IF Name="duedate" -->
> @@ -392,12 +431,16 @@ function Dopop(link) {
>                 <!-- /TMPL_IF -->
>             </td>
>             <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!--
> TMPL_VAR Name="itembiblionumber" -->">
> -                    <!-- TMPL_VAR Name="itemtitle" escape="html"
> --></a></td>
> -                       <td><!-- TMPL_VAR Name="itemauthor" --></td>
> -            <td><a href="/cgi-bin/koha/catalogue/
> moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="itembiblionumber"
> -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR
> NAME="itemnumber" -->"><!-- TMPL_VAR Name="barcode" --></a></td>
> -            <td><!-- TMPL_VAR Name="itemtype" --> <!-- TMPL_VAR
> Name="ccode" --></td>
> +                    <!-- TMPL_VAR Name="itemtitle" escape="html" --></a>
> +                       <!-- TMPL_VAR Name="itemauthor" --></td>
> +            <td><a href="/cgi-bin/koha/catalogue/
> moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="itembiblionumber"
> -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR
> NAME="itemnumber" -->"><!-- TMPL_VAR Name="barcode" --></a>
> +            <!-- TMPL_IF name="itemtype"-->(<!-- TMPL_VAR Name="itemtype"
> -->) <!-- /TMPL_IF --><!-- TMPL_IF Name="ccode"-->(<!-- TMPL_VAR
> Name="ccode" -->)<!-- /TMPL_IF --></td>
> +            <td><!-- TMPL_VAR NAME="homebranch" --></td>
> +            <td><!-- TMPL_VAR NAME="holdingbranch" --></td>
> +            <td><!-- TMPL_VAR NAME="itemlocation" --></td>
> +            <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
>                        <td><!-- TMPL_IF Name="duedate" -->
> -                <a href="/cgi-bin/koha/members/
> moremember.pl?borrowernumber=<!-- TMPL_VAR Name="borrowernumber" -->">
> +                <a href="/cgi-bin/koha/circ/
> circulation.pl?borrowernumber=<!-- TMPL_VAR Name="borrowernumber" -->">
>                     <!-- TMPL_VAR Name="borsurname" -->, <!-- TMPL_VAR
> Name="borfirstname" --> (<!-- TMPL_VAR name="borcategorycode" -->)
>                 </a>
>             <!-- TMPL_ELSE -->Not checked out<!-- /TMPL_IF --></td>
> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl
> b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl
> index 53f9138..004866a 100644
> --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl
> +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tmpl
> @@ -22,11 +22,14 @@ function check() {
>        var msg = "";
>        var count_reserv = 0;
>        var alreadyreserved = 0;
> -
> +    var hold_type="";
>     // check if we have checkitem form
>     if (document.form.checkitem){
>         for (i=0;i<document.form.checkitem.length;i++){
>             if (document.form.checkitem[i].checked == true) {
> +                if (hold_type=="" || hold_type=="single"){
> +                    hold_type=document.form.hold_type[i].value;
> +                }
>                                count_reserv++ ;
>                        }
>         }
> @@ -49,11 +52,11 @@ function check() {
>     if (count_reserv == "0"){
>                msg += (_("- Please select an item to place a hold") +
> "\n");
>     }
> -    if (count_reserv >= "2"){
> +    if (count_reserv >= "2" && hold_type != "multiple"){
>                msg += (_("- You may only place a hold on one item at a
> time") + "\n");
>     }
>
> -    if (alreadyreserved > "0"){
> +    if (alreadyreserved > "0" && hold_type != "multiple"){
>                msg += (_("- This patron had already placed a hold on this
> item") + "\n" + _("Please cancel the previous hold first") + "\n");
>     }
>
> @@ -393,7 +396,21 @@ function checkMultiHold() {
>     <!-- TMPL_LOOP Name="itemloop" -->
>         <tr class="<!-- TMPL_VAR NAME="backgroundcolor" -->">
>             <td>
> -            <!-- TMPL_IF NAME="available" -->
> +
> +            <!-- TMPL_IF NAME="canholdmultiple" -->
> +                <input type="hidden" name="hold_type" value="multiple" />
> +            <!-- TMPL_ELSIF NAME="available" -->
> +                <input type="hidden" name="hold_type" value="single" />
> +            <!-- TMPL_ELSIF NAME="override" -->
> +                <input type="hidden" name="hold_type" value="single" />
> +            <!-- /TMPL_IF -->
> +           <!-- TMPL_IF NAME="cannothold" -->
> +               <input disabled="disabled" type="radio" name="checkitem"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> +               <img src="/intranet-tmpl/<!-- TMPL_VAR NAME="theme"
> -->/img/famfamfam/silk/cross.png" alt="Cannot be put on hold" />
> +           <!-- TMPL_ELSE -->
> +            <!-- TMPL_IF NAME="canholdmultiple" -->
> +                <input type="checkbox" name="checkitem" value="<!--
> TMPL_VAR NAME="itemnumber" -->" />
> +               <!-- TMPL_ELSIF NAME="available" -->
>                 <input type="radio" name="checkitem" value="<!-- TMPL_VAR
> NAME="itemnumber" -->" />
>             <!-- TMPL_ELSIF NAME="override" -->
>                 <input type="radio" name="checkitem" class="needsoverride"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> @@ -402,6 +419,10 @@ function checkMultiHold() {
>                 <input disabled="disabled" type="radio" name="checkitem"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
>                 <img src="/intranet-tmpl/<!-- TMPL_VAR NAME="theme"
> -->/img/famfamfam/silk/cross.png" alt="Cannot be put on hold" />
>             <!-- /TMPL_IF -->
> +           <!-- TMPL_ELSE -->
> +               <input disabled="disabled" type="radio" name="checkitem"
> value="<!-- TMPL_VAR NAME="itemnumber" -->" />
> +               <img src="/intranet-tmpl/<!-- TMPL_VAR NAME="theme"
> -->/img/famfamfam/silk/cross.png" alt="Cannot be put on hold" />
> +           <!-- /TMPL_IF -->
>             </td>
>             <!-- TMPL_IF NAME="item-level_itypes" -->
>                 <td>
> @@ -581,6 +602,7 @@ function checkMultiHold() {
>   <!-- TMPL_LOOP Name="reserveloop" -->
>   <!-- TMPL_UNLESS Name="__odd__" --><tr class="highlight"><!-- TMPL_ELSE
> --><tr><!-- /TMPL_UNLESS -->
>         <td>
> +          <input type="hidden" name="reservenumber" value="<!-- TMPL_VAR
> NAME="reservenumber" -->" />
>           <input type="hidden" name="borrowernumber" value="<!-- TMPL_VAR
> NAME="borrowernumber" -->" />
>           <input type="hidden" name="biblionumber" value="<!-- TMPL_VAR
> NAME="biblionumber" -->" />
>           <select name="rank-request">
> diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tmpl
> b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tmpl
> index 52ff4cd..3646009 100644
> --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tmpl
> +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tmpl
> @@ -113,28 +113,33 @@
>         var badBib = null;
>         $(".confirmjs:checked").each(function() {
>             var biblioNum = $(this).val();
> -            biblionumbers += biblioNum + "/";
> -            selections += biblioNum + "/";
> +            var separator="/";
> +            biblionumbers += biblioNum + separator;
> +
> +            // Add the pickup location
> +            var branchSel = $("#branch_" + biblioNum);
> +            var branch = "";
> +            if (branchSel.size() > 0) {
> +                 branch = $(branchSel).val();
> +            }
>
>             // If the 'specific copy' radio button is checked
>             if ($("#reqspecific_" + biblioNum + ":checked").size() > 0) {
>                 // Find the selected copy
> -                var item = $(".checkitem_" + biblioNum + ":checked");
> -                if ($(item).size() == 0) {
> +                var items = $(".checkitem_" + biblioNum + ":checked");
> +                if ($(items).size() == 0) {
>                     badBib = biblioNum;
>                     return false;
>                 } else {
> -                  selections += $(item).val();
> +                  $(items).each( function(idx,item){
> +
>  selections+=biblioNum+separator+item.value+separator+branch+separator;
> +                  });
>                 }
>             }
> -            selections += "/";
> -
> -            // Add the pickup location
> -            var branchSel = $("#branch_" + biblioNum);
> -            if (branchSel.size() > 0) {
> -                selections += $(branchSel).val();
> +            else {
> +                selections=biblioNum+separator+separator+branch+separator;
>             }
> -            selections += "/";
> +
>             return true;
>         });
>
> @@ -261,10 +266,17 @@
>                       <input class="single_bib" name="single_bib"
> type="hidden" value="<!-- TMPL_VAR NAME="biblionumber" -->"/>
>                         <span class="confirmjs_hold" title="<!-- TMPL_VAR
> NAME="biblionumber" -->"></span>
>                         <span class="confirm_nonjs">
> +                          <!-- TMPL_IF Name="multi"-->
> +                          <input type="checkbox" class="confirmbox
> checkitem <!-- TMPL_VAR NAME="checkitem_bib" -->"
> +                                 name="<!-- TMPL_VAR NAME="checkitem_bib"
> -->" checked="checked"
> +                                 id="<!-- TMPL_VAR NAME="checkitem_bib"
> -->"
> +                                 value="any" />
> +                          <!--TMPL_ELSE-->
>                           <input type="radio" class="confirmbox checkitem
> <!-- TMPL_VAR NAME="checkitem_bib" -->"
>                                  name="<!-- TMPL_VAR NAME="checkitem_bib"
> -->" checked="checked"
>                                  id="<!-- TMPL_VAR NAME="checkitem_bib"
> -->"
>                                  value="any" />
> +                           <!-- /TMPL_IF -->
>                           <label class="confirm_label" for="<!-- TMPL_VAR
> NAME="checkitem_bib" -->">Next available copy</label>
>                         </span>
>                                        </td>
> @@ -302,7 +314,7 @@
>                                                <!-- TMPL_VAR
> NAME="description" -->
>                       </td>
>                     <!-- /TMPL_UNLESS -->
> -                    <!-- TMPL_IF NAME="showpriority" --><td><!-- TMPL_VAR
> name="rank" --> out of <!-- TMPL_VAR NAME="reservecount" --></td><!--
> /TMPL_IF -->
> +                    <!-- TMPL_IF NAME="showpriority" --><td>You are number
> <!-- TMPL_VAR name="rank" --> in line</td><!-- /TMPL_IF -->
>                    <!-- TMPL_IF NAME="reserve_in_future" -->
>                    <td>
>                        <input name="reserve_date_<!-- TMPL_VAR
> NAME="biblionumber" -->" id="reserve_date_<!-- TMPL_VAR NAME="biblionumber"
> -->" size="10">
> @@ -422,6 +434,7 @@
>
>                     <!-- TMPL_UNLESS NAME="singleBranchMode" -->
>                       <td>
> +                    <!-- TMPL_IF NAME="OPACPickupLocation" -->
>                         <select name="branch" id="branch_<!-- TMPL_VAR
> NAME="biblionumber" -->"
>                           <!-- TMPL_UNLESS NAME="holdable"
> -->disabled="disabled"<!-- /TMPL_UNLESS --> >
>                           <!-- TMPL_LOOP NAME="branchChoicesLoop" -->
> @@ -432,6 +445,9 @@
>                             <!-- /TMPL_IF -->
>                           <!-- /TMPL_LOOP -->
>                         </select>
> +                    <!-- TMPL_ELSE -->
> +                        <input type="hidden" name="branch" id="branch_<!--
> TMPL_VAR NAME="biblionumber" -->" value="<!--TMPL_VAR Name="branch"-->" />
> <!-- TMPL_VAR NAME="branchname" -->
> +                    <!-- /TMPL_IF -->
>                       </td>
>                     <!-- /TMPL_UNLESS -->
>                   </tr>
> @@ -465,8 +481,15 @@
>                             <tr class="<!-- TMPL_VAR NAME="backgroundcolor"
> -->">
>                               <td>
>                                 <!-- TMPL_IF NAME="available" -->
> -                                  <input type="radio" class="checkitem
> checkitem_<!-- TMPL_VAR NAME="biblionumber" -->" name="checkitem_<!--
> TMPL_VAR NAME="biblionumber" -->"
> -                                         value="<!-- TMPL_VAR
> NAME="itemnumber" -->" />
> +                                 <!-- TMPL_UNLESS
> NAME="ReservedForThisBorrower" -->
> +                                      <!-- TMPL_IF
> Name="canholdmultiple"-->
> +                                         <input type="checkbox"
> class="checkitem checkitem_<!-- TMPL_VAR NAME="biblionumber" -->"
> name="checkitem_<!-- TMPL_VAR NAME="biblionumber" -->"
> +                                                value="<!-- TMPL_VAR
> NAME="itemnumber" -->" />
> +                                      <!--TMPL_ELSE-->
> +                                         <input type="radio"
> class="checkitem checkitem_<!-- TMPL_VAR NAME="biblionumber" -->"
> name="checkitem_<!-- TMPL_VAR NAME="biblionumber" -->"
> +                                                value="<!-- TMPL_VAR
> NAME="itemnumber" -->" />
> +                                      <!-- /TMPL_IF -->
> +                                 <!-- /TMPL_UNLESS -->
>                                 <!-- TMPL_ELSE -->
>                                   <input disabled="disabled" type="radio"
> class="checkitem" name="checkitem" value="<!-- TMPL_VAR NAME="itemnumber"
> -->" />
>                                   <img src="/opac-tmpl/<!-- TMPL_VAR
> NAME="theme" -->/famfamfam/silk/cross.png" alt="Cannot be put on hold"
> title="Cannot be put on hold" />
> diff --git a/opac/opac-modrequest.pl b/opac/opac-modrequest.pl
> index 7e2f2e5..0003079 100755
> --- a/opac/opac-modrequest.pl
> +++ b/opac/opac-modrequest.pl
> @@ -42,7 +42,9 @@ my ( $template, $borrowernumber, $cookie ) =
> get_template_and_user(
>  );
>
>  my $biblionumber = $query->param('biblionumber');
> +my $reservenumber = $query->param('reservenumber');
> +
>  if ($biblionumber and $borrowernumber) {
> -       CancelReserve($biblionumber, '', $borrowernumber);
> +       CancelReserve( $reservenumber, $biblionumber );
>  }
>  print $query->redirect("/cgi-bin/koha/opac-user.pl#opac-user-holds");
> diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl
> index 699179b..62dc49f 100755
> --- a/opac/opac-reserve.pl
> +++ b/opac/opac-reserve.pl
> @@ -28,11 +28,12 @@ use C4::Output;
>  use C4::Dates qw/format_date/;
>  use C4::Context;
>  use C4::Members;
> +use C4::Overdues;
>  use C4::Branch; # GetBranches
>  use C4::Debug;
> +use C4::Items;
>  # use Data::Dumper;
>
> -my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves");
>
>  my $query = new CGI;
>  my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
> @@ -77,7 +78,9 @@ if ((! $biblionumbers) && (!
> $query->param('place_reserve'))) {
>
>  # Pass the numbers to the page so they can be fed back
>  # when the hold is confirmed. TODO: Not necessary?
> -$template->param( biblionumbers => $biblionumbers );
> +$template->param( biblionumbers      => $biblionumbers,
> +                 OPACPickupLocation => "" .
> C4::Context->preference("OPACPickupLocation"),
> +             );
>
>  # Each biblio number is suffixed with '/', e.g. "1/2/3/"
>  my @biblionumbers = split /\//, $biblionumbers;
> @@ -91,6 +94,7 @@ if (($#biblionumbers < 0) && (!
> $query->param('place_reserve'))) {
>  my $branch = $query->param('branch') || C4::Context->userenv->{branch} ||
> '' ;
>  ($branches->{$branch}) or $branch = "";     # Confirm branch is real
>  $template->param( branch => $branch );
> +$template->param( branchname => $branches->{$branch}->{branchname} );
>
>  # make branch selection options...
>  my $CGIbranchloop = GetBranchesLoop($branch);
> @@ -247,7 +251,7 @@ if ( $borr->{lost} && ($borr->{lost} eq 1) ) {
>                      lost    => 1
>                     );
>  }
> -if ( $borr->{debarred} && ($borr->{debarred} eq 1) ) {
> +if ( CheckBorrowerDebarred($borrowernumber) ) {
>     $noreserves = 1;
>     $template->param(
>                      message  => 1,
> @@ -257,11 +261,6 @@ if ( $borr->{debarred} && ($borr->{debarred} eq 1) ) {
>
>  my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
>  $template->param( RESERVES => \@reserves );
> -if ( $MAXIMUM_NUMBER_OF_RESERVES && (scalar(@reserves) >=
> $MAXIMUM_NUMBER_OF_RESERVES) ) {
> -    $template->param( message => 1 );
> -    $noreserves = 1;
> -    $template->param( too_many_reserves => scalar(@reserves));
> -}
>  foreach my $res (@reserves) {
>     foreach my $biblionumber (@biblionumbers) {
>         if ( $res->{'biblionumber'} == $biblionumber &&
> $res->{'borrowernumber'} == $borrowernumber) {
> @@ -336,12 +335,21 @@ foreach my $biblioNum (@biblionumbers) {
>         }
>     }
>
> -    $biblioLoopIter{itemTypeDescription} =
> $itemTypes->{$biblioData->{itemtype}}{description};
> +    $biblioLoopIter{itemtype}            = $biblioData->{itemtype};
> +    $biblioLoopIter{itemTypeDescription} = $itemTypes->{
> $biblioData->{itemtype} }{description};
>
>     $biblioLoopIter{itemLoop} = [];
>     my $numCopiesAvailable = 0;
> -    foreach my $itemInfo (@{$biblioData->{itemInfos}}) {
> -        my $itemNum = $itemInfo->{itemnumber};
> +
> +    # $canReserveMultiple is set to "yes" ( >0 ) if multiple items can be
> reserved
> +    # it is set to 0 otherwise. depends on item-level_itypes syspref
> +    # and the list of itypes that can be multiple reserved
> +    my $canReserveMultiple = 0;
> +    unless ( C4::Context->preference("item-level_itypes") ) {
> +        $canReserveMultiple = CanHoldMultipleItems(
> $biblioLoopIter{itemtype} );
> +    }
> +    foreach my $itemInfo ( @{ $biblioData->{itemInfos} } ) {
> +        my $itemNum      = $itemInfo->{itemnumber};
>         my $itemLoopIter = {};
>
>         $itemLoopIter->{itemnumber} = $itemNum;
> @@ -355,6 +363,16 @@ foreach my $biblioNum (@biblionumbers) {
>             $itemLoopIter->{imageurl} = $itemInfo->{imageurl};
>         }
>
> +        # check if the itype is one that can be multiple reserved
> +        if ( C4::Context->preference("item-level_itypes") ) {
> +
> +            # sum canReserveMultiple : if at least one item can be
> multiple reserved, then the flag will be >0
> +            # FIXME : there can be complex & strange cases, where some
> items can be multiple reserved, and some can't
> +            # this case is not managed. Note it may be only theoric, and
> have no real case
> +            $itemLoopIter->{canholdmultiple} = CanHoldMultipleItems(
> $itemInfo->{itype} );
> +            $canReserveMultiple = $canReserveMultiple +
> CanHoldMultipleItems( $itemInfo->{itype} );
> +        }
> +
>         # If the holdingbranch is different than the homebranch, we show
> the
>         # holdingbranch of the document too.
>         if ( $itemInfo->{homebranch} ne $itemInfo->{holdingbranch} ) {
> @@ -371,9 +389,8 @@ foreach my $biblioNum (@biblionumbers) {
>         }
>
>         # checking reserve
> -        my ($reservedate,$reservedfor,$expectedAt) =
> GetReservesFromItemnumber($itemNum);
> -        my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0);
> -
> +        my ( $reservedate, $reservedfor, $expectedAt ) =
> GetReservesFromItemnumber($itemNum);
> +        my $ItemBorrowerReserveInfo = GetMemberDetails( $reservedfor, 0 );
>         if ( defined $reservedate ) {
>             $itemLoopIter->{backgroundcolor} = 'reserved';
>             $itemLoopIter->{reservedate}     = format_date($reservedate);
> @@ -381,6 +398,8 @@ foreach my $biblioNum (@biblionumbers) {
>             $itemLoopIter->{ReservedForSurname}        =
> $ItemBorrowerReserveInfo->{'surname'};
>             $itemLoopIter->{ReservedForFirstname}      =
> $ItemBorrowerReserveInfo->{'firstname'};
>             $itemLoopIter->{ExpectedAtLibrary}         = $expectedAt;
> +            $itemLoopIter->{ReservedForThisBorrower}   = ( $reservedfor eq
> $borrowernumber );
> +            warn "ReservedForThisBorrower: " .
> $itemLoopIter->{ReservedForThisBorrower};
>         }
>
>         $itemLoopIter->{notforloan} = $itemInfo->{notforloan};
> @@ -418,17 +437,7 @@ foreach my $biblioNum (@biblionumbers) {
>         # If there is no loan, return and transfer, we show a checkbox.
>         $itemLoopIter->{notforloan} = $itemLoopIter->{notforloan} || 0;
>
> -        my $branch = C4::Circulation::_GetCircControlBranch($itemLoopIter,
> $borr);
> -
> -        my $branchitemrule = GetBranchItemRule( $branch,
> $itemInfo->{'itype'} );
> -        my $policy_holdallowed = 1;
> -
> -        if ( $branchitemrule->{'holdallowed'} == 0 ||
> -                ( $branchitemrule->{'holdallowed'} == 1 &&
> $borr->{'branchcode'} ne $itemInfo->{'homebranch'} ) ) {
> -            $policy_holdallowed = 0;
> -        }
> -
> -        if (IsAvailableForItemLevelRequest($itemNum) and
> $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum)) {
> +        if (IsAvailableForItemLevelRequest($itemNum) and
> CanItemBeReserved($borrowernumber,$itemNum)) {
>             $itemLoopIter->{available} = 1;
>             $numCopiesAvailable++;
>         }
> @@ -456,11 +465,16 @@ foreach my $biblioNum (@biblionumbers) {
>         $biblioLoopIter{bib_available} = 1;
>         $biblioLoopIter{holdable} = 1;
>     }
> -    if ($biblioLoopIter{already_reserved}) {
> +#    $biblioLoopIter{multi} = $canReserveMultiple;
> +    if ( $biblioLoopIter{already_reserved} && !$canReserveMultiple ) {
>         $biblioLoopIter{holdable} = undef;
> +        #warn "Already_Reserved";
>     }
>     if(not CanBookBeReserved($borrowernumber,$biblioNum)){
> -        $biblioLoopIter{holdable} = undef;
> +       $template->param( message => 1 );
> +       $noreserves = 1;
> +       $template->param( too_many_reserves => scalar(@reserves));
> +       $biblioLoopIter{holdable} = undef;
>     }
>
>     push @$biblioLoop, \%biblioLoopIter;
> diff --git a/reserve/modrequest.pl b/reserve/modrequest.pl
> index eecd86b..d65cdc3 100755
> --- a/reserve/modrequest.pl
> +++ b/reserve/modrequest.pl
> @@ -41,12 +41,13 @@ my ( $template, $loggedinuser, $cookie ) =
> get_template_and_user(
>     }
>  );
>
> -my @rank=$query->param('rank-request');
> -my @biblionumber=$query->param('biblionumber');
> -my @borrower=$query->param('borrowernumber');
> -my @branch=$query->param('pickup');
> -my @itemnumber=$query->param('itemnumber');
> -my $multi_hold = $query->param('multi_hold');
> +my @rank          = $query->param('rank-request');
> +my @reservenumber = $query->param('reservenumber');
> +my @biblionumber  = $query->param('biblionumber');
> +my @borrower      = $query->param('borrowernumber');
> +my @branch        = $query->param('pickup');
> +my @itemnumber    = $query->param('itemnumber');
> +my $multi_hold    = $query->param('multi_hold');
>  my $biblionumbers = $query->param('biblionumbers');
>  my $count=@rank;
>
> @@ -54,9 +55,9 @@ my
> $CancelBiblioNumber=$query->param('CancelBiblioNumber');
>  my $CancelBorrowerNumber=$query->param('CancelBorrowerNumber');
>  my $CancelItemnumber=$query->param('CancelItemnumber');
>
> -# 2 possibilitys : cancel an item reservation, or modify or cancel the
> queded list
> +# 2 possibilitys : cancel an item reservation, or modify or cancel the
> queued list
>
> -# 1) cancel an item reservation by fonction ModReserveCancelAll (in
> reserves.pm)
> +# 1) cancel an item reservation by function ModReserveCancelAll (in
> reserves.pm)
>  if ($CancelBorrowerNumber) {
>     ModReserveCancelAll($CancelItemnumber, $CancelBorrowerNumber);
>     $biblionumber[0] = $CancelBiblioNumber,
> @@ -66,7 +67,7 @@ if ($CancelBorrowerNumber) {
>  else {
>     for (my $i=0;$i<$count;$i++){
>         undef $itemnumber[$i] unless $itemnumber[$i] ne '';
> -
>  ModReserve($rank[$i],$biblionumber[$i],$borrower[$i],$branch[$i],$itemnumber[$i]);
> #from C4::Reserves
> +
>  ModReserve($rank[$i],$biblionumber[$i],$borrower[$i],$branch[$i],$itemnumber[$i],$reservenumber[$i]);
> #from C4::Reserves
>     }
>  }
>  my $from=$query->param('from');
> diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl
> index bc3fc74..5920e79 100755
> --- a/reserve/placerequest.pl
> +++ b/reserve/placerequest.pl
> @@ -3,7 +3,6 @@
>  #script to place reserves/requests
>  #writen 2/1/00 by chris at katipo.oc.nz
>
> -
>  # Copyright 2000-2002 Katipo Communications
>  #
>  # This file is part of Koha.
> @@ -37,34 +36,34 @@ my $input = CGI->new();
>
>  my ($user, $cookie, $sesion_id, $flags) = checkauth($input, 0, {
> reserveforothers => 'place_holds' }, 'intranet');
>
> -my @bibitems=$input->param('biblioitem');
> +my @bibitems = $input->param('biblioitem');
>  # FIXME I think reqbib does not exist anymore, it's used in line 82, to
> AddReserve of contraint type 'o'
>  #       I bet it's a 2.x feature, reserving a given biblioitem, that is
> useless in Koha 3.0
>  #       we can remove this line, the AddReserve of constrainttype 'o',
>  #       and probably remove the reserveconstraint table as well, I never
> could fill anything in this table.
> -my @reqbib=$input->param('reqbib');
> -my $biblionumber=$input->param('biblionumber');
> -my $borrower=$input->param('member');
> -my $notes=$input->param('notes');
> -my $branch=$input->param('pickup');
> -my $startdate=$input->param('reserve_date') || '';
> -my @rank=$input->param('rank-request');
> -my $type=$input->param('type');
> -my $title=$input->param('title');
> -my $borrowernumber=GetMember('cardnumber'=>$borrower);
> -my $checkitem=$input->param('checkitem');
> +#my @reqbib         = $input->param('reqbib');
> +my $biblionumber   = $input->param('biblionumber');
> +my $borrower       = $input->param('member');
> +my $notes          = $input->param('notes');
> +my $branch         = $input->param('pickup');
> +my $startdate      = $input->param('reserve_date') || '';
> +my @rank           = $input->param('rank-request');
> +my $type           = $input->param('type');
> +my $title          = $input->param('title');
> +my $borrowernumber = GetMember( 'cardnumber' => $borrower );
> +my @checkitems     = $input->param('checkitem');
>  my $expirationdate = $input->param('expiration_date');
>
> -my $multi_hold = $input->param('multi_hold');
> -my $biblionumbers = $multi_hold ? $input->param('biblionumbers') :
> ($biblionumber . '/');
> -my $bad_bibs = $input->param('bad_bibs');
> +my $multi_hold    = $input->param('multi_hold');
> +my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : (
> $biblionumber . '/' );
> +my $bad_bibs      = $input->param('bad_bibs');
>
>  my %bibinfos = ();
>  my @biblionumbers = split '/', $biblionumbers;
>  foreach my $bibnum (@biblionumbers) {
>     my %bibinfo = ();
> -    $bibinfo{title} = $input->param("title_$bibnum");
> -    $bibinfo{rank} = $input->param("rank_$bibnum");
> +    $bibinfo{title}    = $input->param("title_$bibnum");
> +    $bibinfo{rank}     = $input->param("rank_$bibnum");
>     $bibinfos{$bibnum} = \%bibinfo;
>  }
>
> @@ -72,27 +71,28 @@ my $found;
>
>  # if we have an item selectionned, and the pickup branch is the same as
> the holdingbranch
>  # of the document, we force the value $rank and $found .
> -if ($checkitem ne ''){
> -    $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns');
> -    my $item = $checkitem;
> -    $item = GetItem($item);
> -    if ( $item->{'holdingbranch'} eq $branch ){
> -        $found = 'W' unless
> C4::Context->preference('ReservesNeedReturns');
> +for my $item (@checkitems){
> +    if ( $item ne '' ) {
> +        $rank[0] = '0' unless
> C4::Context->preference('ReservesNeedReturns');
> +        my $itemdata = GetItem($item);
> +        if ( $itemdata->{'holdingbranch'} eq $branch ) {
> +            $found = 'W' unless
> C4::Context->preference('ReservesNeedReturns');
> +        }
>     }
>  }
>
> -if ($type eq 'str8' && $borrowernumber ne ''){
> +if ( $type eq 'str8' && $borrowernumber ne '' ) {
>
> -    foreach my $biblionumber (keys %bibinfos) {
> -        my $count=@bibitems;
> -        @bibitems=sort @bibitems;
> -        my $i2=1;
> +    foreach my $biblionumber ( keys %bibinfos ) {
> +        my $count = @bibitems;
> +        @bibitems = sort @bibitems;
> +        my $i2 = 1;
>         my @realbi;
> -        $realbi[0]=$bibitems[0];
> -        for (my $i=1;$i<$count;$i++) {
> -            my $i3=$i2-1;
> -            if ($realbi[$i3] ne $bibitems[$i]) {
> -                $realbi[$i2]=$bibitems[$i];
> +        $realbi[0] = $bibitems[0];
> +        for ( my $i = 1 ; $i < $count ; $i++ ) {
> +            my $i3 = $i2 - 1;
> +            if ( $realbi[$i3] ne $bibitems[$i] ) {
> +                $realbi[$i2] = $bibitems[$i];
>                 $i2++;
>             }
>         }
> @@ -101,17 +101,17 @@ if ($type eq 'str8' && $borrowernumber ne ''){
>         if ($multi_hold) {
>             my $bibinfo = $bibinfos{$biblionumber};
>
> AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',[$biblionumber],
> -
> $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found);
> +
> $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitems[0],$found);
>         } else {
> -            if ($input->param('request') eq 'any'){
> +            if ( lc($input->param('request')) eq 'any' ) {
>                 # place a request on 1st available
> -
>  AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,$found);
> -            } elsif ($reqbib[0] ne ''){
> -                # FIXME : elsif probably never reached, (see top of the
> script)
> -                # place a request on a given item
> -
>  AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'o',\@reqbib,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,
> $found);
> +
>  AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,undef,$found);
>             } else {
> -
>  AddReserve($branch,$borrowernumber->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,
> $found);
> +                for my $item (@checkitems){
> +                AddReserve( $branch, $borrowernumber->{'borrowernumber'},
> +                    $biblionumber, 'a', \@realbi, $rank[0], $startdate,
> $expirationdate, $notes, $title, $item, $found );
> +                $rank[0]++;
> +                }
>             }
>         }
>     }
> @@ -124,8 +124,8 @@ if ($type eq 'str8' && $borrowernumber ne ''){
>     } else {
>         print $input->redirect("request.pl?biblionumber=$biblionumber");
>     }
> -} elsif ($borrowernumber eq ''){
> -       print $input->header();
> -       print "Invalid card number please try again";
> -       print $input->Dump;
> +} elsif ( $borrowernumber eq '' ) {
> +    print $input->header();
> +    print "Invalid card number please try again";
> +    print $input->Dump;
>  }
> diff --git a/reserve/renewscript.pl b/reserve/renewscript.pl
> index ad746c9..7e65440 100755
> --- a/reserve/renewscript.pl
> +++ b/reserve/renewscript.pl
> @@ -28,6 +28,13 @@ use C4::Circulation;
>  use C4::Auth;
>  use URI::Escape;
>  use C4::Dates qw/format_date_in_iso/;
> +use C4::Context;
> +use C4::Overdues; #CheckBorrowerDebarred
> +use C4::Members; #GetMemberDetail
> +use C4::Items;
> +use C4::Branch;
> +use JSON;
> +use C4::Reserves;
>  my $input = new CGI;
>
>  #Set Up User_env
> @@ -48,6 +55,7 @@ my ( $template, $loggedinuser, $cookie ) =
> get_template_and_user(
>  # find items to renew, all items or a selection of items
>  #
>
> +my $branches = GetBranches();
>  my @data;
>  if ($input->param('renew_all')) {
>     @data = $input->param('all_items[]');
> @@ -80,12 +88,12 @@ my $override_limit = $input->param("override_limit") ||
> 0;
>  my $failedrenews = q{};
>  foreach my $itemno (@data) {
>     # check status before renewing issue
> -       my ($renewokay,$error) =
> CanBookBeRenewed($borrowernumber,$itemno,$override_limit);
> -    if ($renewokay){
> +       my ($renewokay,$error) = CanBookBeRenewed($borrowernumber,$itemno);
> +    if ($renewokay||$override_limit){
>         AddRenewal($borrowernumber,$itemno,$branch,$datedue);
>     }
>        else {
> -               $failedrenews.="&failedrenew=$itemno";
> +
> $failedrenews.="&failedrenew=$itemno&renewerror=".encode_json($error);
>        }
>  }
>  my $failedreturn = q{};
> @@ -93,7 +101,48 @@ foreach my $barcode (@barcodes) {
>     # check status before renewing issue
>    my ( $returned, $messages, $issueinformation, $borrower ) =
>     AddReturn($barcode, $branch, $exemptfine);
> -   $failedreturn.="&failedreturn=$barcode" unless ($returned);
> +    my $itemnumber=GetItemnumberFromBarcode($barcode);
> +    if ($returned){
> +        if (my
> ($reservetype,$reserve)=C4::Reserves::CheckReserves(undef,$barcode)){
> +            if ($reservetype eq "Waiting" || $reservetype eq "Reserved"){
> +                my $transfer=C4::Context->userenv->{branch} ne
> $reserve->{branchcode};
> +                ModReserveAffect( $itemnumber, $reserve->{borrowernumber},
> $transfer, $reserve->{"reservenumber"} );
> +                my ( $message_reserve, $nextreservinfo ) =
> GetOtherReserves($itemnumber);
> +
> +                my ($borr) = GetMemberDetails( $nextreservinfo, 0 );
> +                $messages->{reservesdata}={
> +                        found          => 1,
> +                        currentbranch  =>
> $branches->{C4::Context->userenv->{branch}}->{'branchname'},
> +                        destbranchname => $branches->{
> $reserve->{'branchcode'} }->{'branchname'},
> +                        name           => $borr->{'surname'} . ", " .
> $borr->{'title'} . " " . $borr->{'firstname'},
> +                        borfirstname   => $borr->{'firstname'},
> +                        borsurname     => $borr->{'surname'},
> +                        bortitle       => $borr->{'title'},
> +                        borphone       => $borr->{'phone'},
> +                        boremail       => $borr->{'email'},
> +                        boraddress     => $borr->{'address'},
> +                        boraddress2    => $borr->{'address2'},
> +                        borcity        => $borr->{'city'},
> +                        borzip         => $borr->{'zipcode'},
> +                        borcnum        => $borr->{'cardnumber'},
> +                        debarred       =>
> CheckBorrowerDebarred($borr->{borrowernumber}),
> +                        gonenoaddress  => $borr->{'gonenoaddress'},
> +                        barcode        => $barcode,
> +                        transfertodo   => $transfer,
> +                        destbranch        => $reserve->{'branchcode'},
> +                        reservenumber  => $reserve->{'reservenumber'},
> +                        borrowernumber => $reserve->{'borrowernumber'},
> +                        itemnumber     => $reserve->{'itemnumber'},
> +                        biblionumber   => $reserve->{'biblionumber'},
> +                        reservenotes   => $reserve->{'reservenotes'},
> +                };
> +
> +            }
> +        }
> +    }
> +    if (!$returned ||$messages){
> +
>  $failedreturn.="&failedreturn=$barcode&returnerror=".encode_json($messages);
> +    }
>  }
>
>  #
> diff --git a/reserve/request.pl b/reserve/request.pl
> index 7e51364..fb60098 100755
> --- a/reserve/request.pl
> +++ b/reserve/request.pl
> @@ -38,6 +38,7 @@ use C4::Biblio;
>  use C4::Items;
>  use C4::Koha;
>  use C4::Circulation;
> +use C4::IssuingRules;
>  use C4::Dates qw/format_date/;
>  use C4::Members;
>  use C4::Search;                # enabled_staff_search_views
> @@ -142,8 +143,8 @@ if ($cardnumber) {
>     my $number_reserves =
>       GetReserveCount( $borrowerinfo->{'borrowernumber'} );
>
> -    if ( $number_reserves > C4::Context->preference('maxreserves') ) {
> -               $warnings = 1;
> +    if ( not CanBookBeReserved( $borrowerinfo->{borrowernumber},
> $input->param('biblionumber') ) ) {
> +               $warnings = 1;
>         $maxreserves = 1;
>     }
>
> @@ -151,7 +152,7 @@ if ($cardnumber) {
>     my $expiry_date = $borrowerinfo->{dateexpiry};
>     my $expiry = 0; # flag set if patron account has expired
>     if ($expiry_date and $expiry_date ne '0000-00-00' and
> -            Date_to_Days(split /-/,$date) > Date_to_Days(split
> /-/,$expiry_date)) {
> +            Date_to_Days(split (/-/,$date)) > Date_to_Days(split
> (/-/,$expiry_date))) {
>                $messages = $expiry = 1;
>     }
>
> @@ -224,7 +225,7 @@ my $borrowerinfo = GetMemberDetails( 0, $cardnumber );
>  my @biblionumbers = ();
>  my $biblionumbers = $input->param('biblionumbers');
>  if ($multihold) {
> -    @biblionumbers = split '/', $biblionumbers;
> +    @biblionumbers = split ('/', $biblionumbers);
>  } else {
>     push @biblionumbers, $input->param('biblionumber');
>  }
> @@ -250,8 +251,11 @@ foreach my $biblionumber (@biblionumbers) {
>         if ( defined $res->{found} && $res->{found} eq 'W' ) {
>             $count--;
>         }
> -
> -        if ( defined $borrowerinfo && ($borrowerinfo->{borrowernumber} eq
> $res->{borrowernumber}) ) {
> +        if ($res->{itemnumber} && not $res->{itemtype}){
> +
>  $res->{itemtype}=GetItem($res->{itemnumber},$res->{biblionumber})->{itype};
> +        }
> +        next if CanHoldMultipleItems($res->{itemtype});
> +        if ( defined $borrowerinfo && ($borrowerinfo->{borrowernumber} eq
> $res->{borrowernumber}) && !CanHoldMultipleItems($res->{itemtype}) ) {
>             $warnings = 1;
>             $alreadyreserved = 1;
>             $biblioloopiter{warn} = 1;
> @@ -414,24 +418,16 @@ foreach my $biblionumber (@biblionumbers) {
>                     }
>                 }
>             }
> -
> -            my $branch = C4::Circulation::_GetCircControlBranch($item,
> $borrowerinfo);
>
> -            my $branchitemrule = GetBranchItemRule( $branch,
> $item->{'itype'} );
> -            my $policy_holdallowed = 1;
> -
> -            $item->{'holdallowed'} = $branchitemrule->{'holdallowed'};
> -
> -            if ( $branchitemrule->{'holdallowed'} == 0 ||
> -                 ( $branchitemrule->{'holdallowed'} == 1 &&
> $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) {
> -                $policy_holdallowed = 0;
> -            }
> +            my $branchitemrule = GetIssuingRule(
> $borrowerinfo->{categorycode}, $item->{'itype'}, GetReservesControlBranch(
> $borrowerinfo, $item ) );
> +            my $policy_holdrestricted =
> $branchitemrule->{'reservesallowed'};
> +            $item->{'holdrestricted'} =
> $branchitemrule->{'holdrestricted'};
>
>             if (IsAvailableForItemLevelRequest($itemnumber) and not
> $item->{cantreserve} and CanItemBeReserved($borrowerinfo->{borrowernumber},
> $itemnumber) ) {
> -                if ( not $policy_holdallowed and C4::Context->preference(
> 'AllowHoldPolicyOverride' ) ) {
> +                if ( not $policy_holdrestricted and
> C4::Context->preference( 'AllowHoldPolicyOverride' ) ) {
>                     $item->{override} = 1;
>                     $num_override++;
> -                } elsif ( $policy_holdallowed ) {
> +                } elsif ( $policy_holdrestricted ) {
>                     $item->{available} = 1;
>                     $num_available++;
>                 }
> @@ -447,10 +443,17 @@ foreach my $biblionumber (@biblionumbers) {
>             while (my $wait_hashref = $sth2->fetchrow_hashref) {
>                 $item->{waitingdate} =
> format_date($wait_hashref->{waitingdate});
>             }
> +
> +            if ( BorrowerHasReserve( $borrowerinfo->{'borrowernumber'},
> '', $itemnumber ) ) {
> +              $item->{available} = 0;
> +              $item->{override} = 0;
> +            }
> +            $item->{canholdmultiple}=CanHoldMultipleItems($item->{itype})
> && $item->{available};
> +           $item->{cannothold}=!CanHoldMultipleItems($item->{itype});
> +
>             push @{ $biblioitem->{itemloop} }, $item;
>         }
> -
> -        if ( $num_override == scalar( @{ $biblioitem->{itemloop} } ) ) { #
> That is, if all items require an override
> +        if ( $num_override > 0) {
>             $template->param( override_required => 1 );
>         } elsif ( $num_available == 0 ) {
>             $template->param( none_available => 1 );
> @@ -471,6 +474,9 @@ foreach my $biblionumber (@biblionumbers) {
>             $a_found cmp $b_found;
>         } @$reserves ) {
>         my %reserve;
> +
> +        $reserve{'reservenumber'}   = $res->{'reservenumber'};
> +
>         my @optionloop;
>         for ( my $i = 1 ; $i <= $totalcount ; $i++ ) {
>             push(
> diff --git a/t/lib/KohaTest/Circulation.pm b/t/lib/KohaTest/Circulation.pm
> index 7d5e69d..8236bcb 100644
> --- a/t/lib/KohaTest/Circulation.pm
> +++ b/t/lib/KohaTest/Circulation.pm
> @@ -20,8 +20,6 @@ sub methods : Test( 1 ) {
>                       CanBookBeIssued
>                       AddIssue
>                       GetLoanLength
> -                      GetIssuingRule
> -                      GetBranchBorrowerCircRule
>                       AddReturn
>                       MarkIssueReturned
>                       _FixOverduesOnReturn
> diff --git a/t/lib/KohaTest/Members/GetMemberDetails.pm
> b/t/lib/KohaTest/Members/GetMemberDetails.pm
> index e93742b..d75c60e 100644
> --- a/t/lib/KohaTest/Members/GetMemberDetails.pm
> +++ b/t/lib/KohaTest/Members/GetMemberDetails.pm
> @@ -50,12 +50,10 @@ sub startup_create_detailed_borrower : Test( startup =>
> 2 ) {
>     $description = 'Test account';
>     $type        = 'M';
>     $amount      = 5.00;
> -    $user        = '';
> +    $note        = '';
>
>     my $acct_added =
> -      C4::Accounts::manualinvoice( $borrowernumber, undef, $description,
> $type, $amount,
> -        $user );
> -
> +      C4::Accounts::manualinvoice( $borrowernumber, undef, $description,
> $type, $amount, $note );
>     ok( $acct_added == 0, 'added account for borrower' );
>
>     $self->{amountoutstanding} = $amount;
> diff --git a/t/lib/KohaTest/Overdues.pm b/t/lib/KohaTest/Overdues.pm
> index 949c670..02b907e 100644
> --- a/t/lib/KohaTest/Overdues.pm
> +++ b/t/lib/KohaTest/Overdues.pm
> @@ -23,7 +23,6 @@ sub methods : Test( 1 ) {
>                        BorType
>                        ReplacementCost
>                        GetFine
> -                       GetIssuingRules
>                        ReplacementCost2
>                        GetNextIdNotify
>                        NumberNotifyId
> --
> 1.7.1
>
>
> _______________________________________________
> Koha-patches mailing list
> Koha-patches at lists.koha-community.org
> http://lists.koha-community.org/cgi-bin/mailman/listinfo/koha-patches
> website : http://www.koha-community.org/
> git : http://git.koha-community.org/
> bugs : http://bugs.koha-community.org/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/koha-patches/attachments/20101216/01fd89c9/attachment-0001.htm>


More information about the Koha-patches mailing list