X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FCirculation.pm;h=e68db64a78c3d33fb1873a2828f3a4dd4e390d6c;hb=refs%2Fheads%2Fffzg-1059-zebra_spine_label;hp=47068f9e58177bcfa23cdbd5afe795d7038b12e4;hpb=afa94246d3d13993b7add9b34b40be977945f8fd;p=koha.git diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 47068f9e58..e68db64a78 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -24,7 +24,6 @@ use strict; use C4::Context; use C4::Stats; use C4::Reserves; -use C4::Koha; use C4::Biblio; use C4::Items; use C4::Members; @@ -43,6 +42,8 @@ use Date::Calc qw( Date_to_Days Day_of_Week Add_Delta_Days + check_date + Delta_Days ); use POSIX qw(strftime); use C4::Branch; # GetBranches @@ -59,8 +60,9 @@ BEGIN { # FIXME subs that should probably be elsewhere push @EXPORT, qw( - &FixOverduesOnReturn &barcodedecode + &LostItem + &ReturnLostItem ); # subs to deal with issuing a book @@ -72,7 +74,6 @@ BEGIN { &GetRenewCount &GetItemIssue &GetItemIssues - &GetBorrowerIssues &GetIssuingCharges &GetIssuingRule &GetBranchBorrowerCircRule @@ -319,7 +320,7 @@ sub transferbook { # find reserves..... # That'll save a database query. - my ( $resfound, $resrec ) = + my ( $resfound, $resrec, undef ) = CheckReserves( $itemnumber ); if ( $resfound and not $ignoreRs ) { $resrec->{'ResFound'} = $resfound; @@ -578,7 +579,7 @@ C<$issuingimpossible> and C<$needsconfirmation> are some hashref. =over 4 -=item C<$borrower> hash with borrower informations (from GetMemberDetails) +=item C<$borrower> hash with borrower informations (from GetMember or GetMemberDetails) =item C<$barcode> is the bar code of the book being issued. @@ -817,7 +818,7 @@ sub CanBookBeIssued { } } } - if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) + if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} > 0 ) { $issuingimpossible{WTHDRAWN} = 1; } @@ -858,7 +859,7 @@ sub CanBookBeIssued { elsif ($issue->{borrowernumber}) { # issued to someone else - my $currborinfo = C4::Members::GetMemberDetails( $issue->{borrowernumber} ); + my $currborinfo = C4::Members::GetMember( borrowernumber => $issue->{borrowernumber} ); # warn "=>.$currborinfo->{'firstname'} $currborinfo->{'surname'} ($currborinfo->{'cardnumber'})"; $needsconfirmation{ISSUED_TO_ANOTHER} = 1; @@ -869,10 +870,10 @@ sub CanBookBeIssued { } # See if the item is on reserve. - my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); + my ( $restype, $res, undef ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); if ($restype) { my $resbor = $res->{'borrowernumber'}; - my ( $resborrower ) = C4::Members::GetMemberDetails( $resbor, 0 ); + my ( $resborrower ) = C4::Members::GetMember( borrowernumber => $resbor ); my $branches = GetBranches(); my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'}; if ( $resbor ne $borrower->{'borrowernumber'} && $restype eq "Waiting" ) @@ -909,7 +910,7 @@ Issue a book. Does no check, they are done in CanBookBeIssued. If we reach this =over 4 -=item C<$borrower> is a hash with borrower informations (from GetMemberDetails). +=item C<$borrower> is a hash with borrower informations (from GetMember or GetMemberDetails). =item C<$barcode> is the barcode of the item being issued. @@ -983,39 +984,7 @@ sub AddIssue { ); } - # See if the item is on reserve. - my ( $restype, $res ) = - C4::Reserves::CheckReserves( $item->{'itemnumber'} ); - if ($restype) { - my $resbor = $res->{'borrowernumber'}; - if ( $resbor eq $borrower->{'borrowernumber'} ) { - # The item is reserved by the current patron - ModReserveFill($res); - } - elsif ( $restype eq "Waiting" ) { - # warn "Waiting"; - # The item is on reserve and waiting, but has been - # reserved by some other patron. - } - elsif ( $restype eq "Reserved" ) { - # warn "Reserved"; - # The item is reserved by someone else. - if ($cancelreserve) { # cancel reserves on this item - CancelReserve(0, $res->{'itemnumber'}, $res->{'borrowernumber'}); - } - } - if ($cancelreserve) { - CancelReserve($res->{'biblionumber'}, 0, $res->{'borrowernumber'}); - } - else { - # set waiting reserve to first in reserve queue as book isn't waiting now - ModReserve(1, - $res->{'biblionumber'}, - $res->{'borrowernumber'}, - $res->{'branchcode'} - ); - } - } + MoveReserve( $item->{'itemnumber'}, $borrower->{'borrowernumber'}, $cancelreserve ); # Starting process for transfer job (checking transfert and validate it if we have one) my ($datesent) = GetTransfers($item->{'itemnumber'}); @@ -1056,6 +1025,12 @@ sub AddIssue { CartToShelf( $item->{'itemnumber'} ); } $item->{'issues'}++; + + ## If item was lost, it has now been found, reverse any list item charges if neccessary. + if ( $item->{'itemlost'} ) { + _FixAccountForLostAndReturned( $item->{'itemnumber'}, undef, $item->{'barcode'} ); + } + ModItem({ issues => $item->{'issues'}, holdingbranch => C4::Context->userenv->{'branch'}, itemlost => 0, @@ -1515,7 +1490,8 @@ sub AddReturn { my $biblio; my $doreturn = 1; my $validTransfert = 0; - + my $stat_type = 'return'; + # get information on item my $itemnumber = GetItemnumberFromBarcode( $barcode ); unless ($itemnumber) { @@ -1532,6 +1508,11 @@ sub AddReturn { # even though item is not on loan, it may still be transferred; therefore, get current branch info $doreturn = 0; # No issue, no borrowernumber. ONLY if $doreturn, *might* you have a $borrower later. + # Record this as a local use, instead of a return, if the RecordLocalUseOnReturn is on + if (C4::Context->preference("RecordLocalUseOnReturn")) { + $messages->{'LocalUse'} = 1; + $stat_type = 'localuse'; + } } my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed"; @@ -1626,11 +1607,15 @@ sub AddReturn { if ($borrowernumber) { 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); } # find reserves..... # if we don't have a reserve with the status W, we launch the Checkreserves routine - my ($resfound, $resrec) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); + my ($resfound, $resrec, undef) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); if ($resfound) { $resrec->{'ResFound'} = $resfound; $messages->{'ResFound'} = $resrec; @@ -1639,7 +1624,7 @@ sub AddReturn { # update stats? # Record the fact that this book was returned. UpdateStats( - $branch, 'return', '0', '', + $branch, $stat_type, '0', '', $item->{'itemnumber'}, $biblio->{'itemtype'}, $borrowernumber @@ -1749,6 +1734,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( '-', @newdate ); + my ( $deby, $debm, $debd ) = split( /-/, $borrower->{debarred} ); + if ( check_date( $deby, $debm, $debd ) ) { + my @olddate = split( /-/, $borrower->{debarred} ); + + if ( Delta_Days( @olddate, @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); @@ -1832,10 +1872,11 @@ sub _FixAccountForLostAndReturned { my $item_id = @_ ? shift : $itemnumber; # Send the barcode if you want that logged in the description my $dbh = C4::Context->dbh; # check for charge made for lost book - my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE (itemnumber = ?) AND (accounttype='L' OR accounttype='Rep') ORDER BY date DESC"); + my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE itemnumber = ? AND accounttype IN ('L', 'Rep', 'W') ORDER BY date DESC, accountno DESC"); $sth->execute($itemnumber); my $data = $sth->fetchrow_hashref; $data or return; # bail if there is nothing to do + $data->{accounttype} eq 'W' and return; # Written off # writeoff this amount my $offset; @@ -2193,7 +2234,7 @@ sub CanBookBeRenewed { $error="too_many"; } - my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber); + my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves($itemnumber); if ($resfound) { $renewokay = 0; $error="on_reserve" @@ -2255,7 +2296,7 @@ sub AddRenewal { # based on the value of the RenewalPeriodBase syspref. unless ($datedue) { - my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef; + my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ) or return undef; my $itemtype = (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'}; $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ? @@ -2309,7 +2350,7 @@ sub GetRenewCount { my $renewsallowed = 0; my $renewsleft = 0; - my $borrower = C4::Members::GetMemberDetails($bornum); + my $borrower = C4::Members::GetMember( borrowernumber => $bornum); my $item = GetItem($itemno); # Look in the issues table for this item, lent to this borrower, @@ -2943,8 +2984,44 @@ sub DeleteBranchTransferLimits { $sth->execute(); } +sub ReturnLostItem{ + my ( $borrowernumber, $itemnum ) = @_; + + MarkIssueReturned( $borrowernumber, $itemnum ); + my $borrower = C4::Members::GetMember( 'borrowernumber'=>$borrowernumber ); + my @datearr = localtime(time); + my $date = ( 1900 + $datearr[5] ) . "-" . ( $datearr[4] + 1 ) . "-" . $datearr[3]; + my $bor = "$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}"; + ModItem({ paidfor => "Paid for by $bor $date" }, undef, $itemnum); +} + + +sub LostItem{ + my ($itemnumber, $mark_returned, $charge_fee) = @_; + + my $dbh = C4::Context->dbh(); + my $sth=$dbh->prepare("SELECT issues.*,items.*,biblio.title + FROM issues + JOIN items USING (itemnumber) + JOIN biblio USING (biblionumber) + WHERE issues.itemnumber=?"); + $sth->execute($itemnumber); + my $issues=$sth->fetchrow_hashref(); + $sth->finish; + + # if a borrower lost the item, add a replacement cost to the their record + if ( my $borrowernumber = $issues->{borrowernumber} ){ + + C4::Accounts::chargelostitem($borrowernumber, $itemnumber, $issues->{'replacementprice'}, "Lost Item $issues->{'title'} $issues->{'barcode'}") + if $charge_fee; + #FIXME : Should probably have a way to distinguish this from an item that really was returned. + #warn " $issues->{'borrowernumber'} / $itemnumber "; + MarkIssueReturned($borrowernumber,$itemnumber) if $mark_returned; + } +} + - 1; +1; __END__