X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FCirculation.pm;h=0b6892e78657dc9bb36acb59fb330f02450da145;hb=c43eadf3c77efc317fe14fd347fa4bc68fdfa748;hp=ed906326c0625d17e7d4803c5a8bd33fb06d0b9a;hpb=ef27099d90df2d25290469e2da03d41c926e716e;p=koha.git diff --git a/C4/Circulation.pm b/C4/Circulation.pm index ed906326c0..0b6892e786 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -17,7 +17,6 @@ package C4::Circulation; # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, # Suite 330, Boston, MA 02111-1307 USA -# $Id$ use strict; require Exporter; @@ -26,8 +25,9 @@ use C4::Stats; use C4::Reserves; use C4::Koha; use C4::Biblio; +use C4::Items; use C4::Members; -use C4::Date; +use C4::Dates; use Date::Calc qw( Today Today_and_Now @@ -41,10 +41,50 @@ use POSIX qw(strftime); use C4::Branch; # GetBranches use C4::Log; # logaction -our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,%EXPORT_TAGS); - -# set the version for version checking -$VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v).".".join( "_", map { sprintf "%03d", $_ } @v ); }; +use Data::Dumper; + +use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); + +BEGIN { + # set the version for version checking + $VERSION = 3.01; + @ISA = qw(Exporter); + + # FIXME subs that should probably be elsewhere + push @EXPORT, qw( + &FixOverduesOnReturn + &barcodedecode + ); + + # subs to deal with issuing a book + push @EXPORT, qw( + &CanBookBeIssued + &CanBookBeRenewed + &AddIssue + &AddRenewal + &GetRenewCount + &GetItemIssue + &GetItemIssues + &GetBorrowerIssues + &GetIssuingCharges + &GetBiblioIssues + &AnonymiseIssueHistory + ); + + # subs to deal with returns + push @EXPORT, qw( + &AddReturn + ); + + # subs to deal with transfers + push @EXPORT, qw( + &transferbook + &GetTransfers + &GetTransfersFromTo + &updateWrongTransfer + &DeleteTransfer + ); +} =head1 NAME @@ -62,70 +102,41 @@ Also deals with stocktaking. =head1 FUNCTIONS -=cut - -@ISA = qw(Exporter); - -# FIXME subs that should probably be elsewhere -push @EXPORT, qw( - &FixOverduesOnReturn - &cuecatbarcodedecode -); - -# subs to deal with issuing a book -push @EXPORT, qw( - &CanBookBeIssued - &CanBookBeRenewed - &AddIssue - &AddRenewal - &GetItemIssue - &GetItemIssues - &GetBorrowerIssues - &GetIssuingCharges - &GetBiblioIssues - &AnonymiseIssueHistory -); -# subs to deal with returns -push @EXPORT, qw( - &AddReturn -); - -# subs to deal with transfers -push @EXPORT, qw( - &transferbook - &GetTransfers - &GetTransfersFromTo - &updateWrongTransfer - &DeleteTransfer -); - -# FIXME - At least, I'm pretty sure this is for decoding CueCat stuff. -# FIXME From Paul : i don't understand what this sub does & why it has to be called on every circ. Speak of this with chris maybe ? - =head2 decode =head3 $str = &decode($chunk); =over 4 -=item Decodes a segment of a string emitted by a CueCat barcode scanner and -returns it. +=item Generic filter function for barcode string. =back =cut -sub cuecatbarcodedecode { +# FIXME From Paul : i don't understand what this sub does & why it has to be called on every circ. Speak of this with chris maybe ? +# FIXME -- the &decode fcn below should be wrapped into this one. + +sub barcodedecode { my ($barcode) = @_; - chomp($barcode); - my @fields = split( /\./, $barcode ); - my @results = map( decode($_), @fields[ 1 .. $#fields ] ); - if ( $#results == 2 ) { - return $results[2]; - } - else { - return $barcode; - } + my $filter = C4::Context->preference('itemBarcodeInputFilter'); + if($filter eq 'whitespace') { + $barcode =~ s/\s//g; + return $barcode; + } elsif($filter eq 'cuecat') { + chomp($barcode); + my @fields = split( /\./, $barcode ); + my @results = map( decode($_), @fields[ 1 .. $#fields ] ); + if ( $#results == 2 ) { + return $results[2]; + } + else { + return $barcode; + } + } elsif($filter eq 'T-prefix') { + my $num = ( $barcode =~ /^[Tt] /) ? substr($barcode,2) + 0 : $barcode; + return sprintf( "T%07d",$num); + } } =head2 decode @@ -368,18 +379,29 @@ if the borrower borrows to much things # check if a book can be issued. -sub TooMany ($$) { +sub TooMany { my $borrower = shift; my $biblionumber = shift; + my $item = shift; my $cat_borrower = $borrower->{'categorycode'}; - my $branch_borrower = $borrower->{'branchcode'}; my $dbh = C4::Context->dbh; - - my $sth = - $dbh->prepare('SELECT itemtype FROM biblioitems WHERE biblionumber = ?'); - $sth->execute($biblionumber); - my $type = $sth->fetchrow; - $sth = + my $branch; + # Get which branchcode we need + if (C4::Context->preference('CircControl') eq 'PickupLibary'){ + $branch = C4::Context->userenv->{'branch'}; + } + elsif (C4::Context->preference('CircControl') eq 'PatronLibary'){ + $branch = $borrower->{'branchcode'}; + } + else { + # items home library + $branch = $item->{'homebranch'}; + } + my $type = (C4::Context->preference('item-level_itypes')) + ? $item->{'itype'} # item-level + : $item->{'itemtype'}; # biblio-level + + my $sth = $dbh->prepare( 'SELECT * FROM issuingrules WHERE categorycode = ? @@ -387,15 +409,17 @@ sub TooMany ($$) { AND branchcode = ?' ); - my $sth2 = - $dbh->prepare( - "SELECT COUNT(*) FROM issues i, biblioitems s1, items s2 + my $query2 = "SELECT COUNT(*) FROM issues i, biblioitems s1, items s2 WHERE i.borrowernumber = ? AND i.returndate IS NULL AND i.itemnumber = s2.itemnumber - AND s1.itemtype LIKE ? - AND s1.biblioitemnumber = s2.biblioitemnumber" - ); + AND s1.biblioitemnumber = s2.biblioitemnumber"; + if (C4::Context->preference('item-level_itypes')){ + $query2.=" AND s2.itype=? "; + } else { + $query2.=" AND s1.itemtype= ? "; + } + my $sth2= $dbh->prepare($query2); my $sth3 = $dbh->prepare( 'SELECT COUNT(*) FROM issues @@ -405,22 +429,22 @@ sub TooMany ($$) { my $alreadyissued; # check the 3 parameters (branch / itemtype / category code - $sth->execute( $cat_borrower, $type, $branch_borrower ); + $sth->execute( $cat_borrower, $type, $branch ); my $result = $sth->fetchrow_hashref; -# warn "$cat_borrower, $type, $branch_borrower = ".Data::Dumper::Dumper($result); +# warn "$cat_borrower, $type, $branch = ".Data::Dumper::Dumper($result); if ( $result->{maxissueqty} ne '' ) { # warn "checking on everything set"; - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on branch/category/itemtype failed)" ); } # now checking for total - $sth->execute( $cat_borrower, '', $branch_borrower ); + $sth->execute( $cat_borrower, '*', $branch ); my $result = $sth->fetchrow_hashref; - if ( $result->{maxissueqty} ne '*' ) { - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + if ( $result->{maxissueqty} ne '' ) { + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on branch/category/total failed)" ); @@ -429,22 +453,22 @@ sub TooMany ($$) { } # check the 2 parameters (branch / itemtype / default categorycode - $sth->execute( '*', $type, $branch_borrower ); - my $result = $sth->fetchrow_hashref; -# warn "*, $type, $branch_borrower = ".Data::Dumper::Dumper($result); + $sth->execute( '*', $type, $branch ); + $result = $sth->fetchrow_hashref; +# warn "*, $type, $branch = ".Data::Dumper::Dumper($result); if ( $result->{maxissueqty} ne '' ) { # warn "checking on 2 parameters (default categorycode)"; - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on branch / default category / itemtype failed)" ); } # now checking for total - $sth->execute( '*', '*', $branch_borrower ); + $sth->execute( '*', '*', $branch ); my $result = $sth->fetchrow_hashref; if ( $result->{maxissueqty} ne '' ) { - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on branch / default category / total failed)" ); @@ -454,12 +478,12 @@ sub TooMany ($$) { # check the 1 parameters (default branch / itemtype / categorycode $sth->execute( $cat_borrower, $type, '*' ); - my $result = $sth->fetchrow_hashref; + $result = $sth->fetchrow_hashref; # warn "$cat_borrower, $type, * = ".Data::Dumper::Dumper($result); if ( $result->{maxissueqty} ne '' ) { # warn "checking on 1 parameter (default branch + categorycode)"; - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on default branch/category/itemtype failed)" ); @@ -468,7 +492,7 @@ sub TooMany ($$) { $sth->execute( $cat_borrower, '*', '*' ); my $result = $sth->fetchrow_hashref; if ( $result->{maxissueqty} ne '' ) { - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on default branch / category / total failed)" ); @@ -478,29 +502,30 @@ sub TooMany ($$) { # check the 0 parameters (default branch / itemtype / default categorycode $sth->execute( '*', $type, '*' ); - my $result = $sth->fetchrow_hashref; + $result = $sth->fetchrow_hashref; # warn "*, $type, * = ".Data::Dumper::Dumper($result); if ( $result->{maxissueqty} ne '' ) { # warn "checking on default branch and default categorycode"; - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); + $sth2->execute( $borrower->{'borrowernumber'}, $type ); my $alreadyissued = $sth2->fetchrow; if ( $result->{'maxissueqty'} <= $alreadyissued ) { return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on default branch / default category / itemtype failed)" ); } - # now checking for total - $sth->execute( '*', '*', '*' ); - my $result = $sth->fetchrow_hashref; - if ( $result->{maxissueqty} ne '' ) { - $sth2->execute( $borrower->{'borrowernumber'}, "%$type%" ); - my $alreadyissued = $sth2->fetchrow; - if ( $result->{'maxissueqty'} <= $alreadyissued ) { - return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on default branch / default category / total failed)" ); - } - } - } + } + # now checking for total + $sth->execute( '*', '*', '*' ); + $result = $sth->fetchrow_hashref; + if ( $result->{maxissueqty} ne '' ) { + warn "checking total"; + $sth2->execute( $borrower->{'borrowernumber'}, $type ); + my $alreadyissued = $sth2->fetchrow; + if ( $result->{'maxissueqty'} <= $alreadyissued ) { + return ( "$alreadyissued / ".( $result->{maxissueqty} + 0 )." (rule on default branch / default category / total failed)" ); + } + } - #OK, the patron can issue !!! + # OK, the patron can issue !!! return; } @@ -552,12 +577,6 @@ The borrower number of the last three patrons who borrowed this item. sub itemissues { my ( $bibitem, $biblio ) = @_; my $dbh = C4::Context->dbh; - - # FIXME - If this function die()s, the script will abort, and the - # user won't get anything; depending on how far the script has - # gotten, the user might get a blank page. It would be much better - # to at least print an error message. The easiest way to do this - # is to set $SIG{__DIE__}. my $sth = $dbh->prepare("Select * from items where items.biblioitemnumber = ?") || die $dbh->errstr; @@ -590,13 +609,8 @@ sub itemissues { $data->{'borrower'} = $data2->{'borrowernumber'}; } else { - if ( $data->{'wthdrawn'} eq '1' ) { - $data->{'date_due'} = 'Cancelled'; - } - else { - $data->{'date_due'} = 'Available'; - } # else - } # else + $data->{'date_due'} = ($data->{'wthdrawn'} eq '1') ? 'Cancelled' : 'Available'; + } $sth2->finish; @@ -609,15 +623,6 @@ sub itemissues { ORDER BY returndate DESC,timestamp DESC" ); -# $sth2 = $dbh->prepare(" -# SELECT * -# FROM issues -# LEFT JOIN borrowers ON issues.borrowernumber = borrowers.borrowernumber -# WHERE itemnumber = ? -# AND returndate is not NULL -# ORDER BY returndate DESC,timestamp DESC -# "); - $sth2->execute( $data->{'itemnumber'} ); for ( my $i2 = 0 ; $i2 < 2 ; $i2++ ) { # FIXME : error if there is less than 3 pple borrowing this item @@ -639,26 +644,27 @@ sub itemissues { =head2 CanBookBeIssued -$issuingimpossible, $needsconfirmation = - CanBookBeIssued( $borrower, $barcode, $year, $month, $day, $inprocess ); - +( $issuingimpossible, $needsconfirmation ) = + CanBookBeIssued( $borrower, $barcode, $duedatespec, $inprocess ); +C<$duedatespec> is a C4::Dates object. C<$issuingimpossible> and C<$needsconfirmation> are some hashref. =cut sub CanBookBeIssued { - my ( $borrower, $barcode, $year, $month, $day, $inprocess ) = @_; + my ( $borrower, $barcode, $duedate, $inprocess ) = @_; my %needsconfirmation; # filled with problems that needs confirmations my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE my $item = GetItem(GetItemnumberFromBarcode( $barcode )); my $issue = GetItemIssue($item->{itemnumber}); + my $biblioitem = GetBiblioItemData($item->{biblioitemnumber}); + $item->{'itemtype'}=$biblioitem->{'itemtype'}; my $dbh = C4::Context->dbh; # - # DUE DATE is OK ? + # DUE DATE is OK ? -- should already have checked. # - my ( $duedate, $invalidduedate ) = fixdate( $year, $month, $day ); - $issuingimpossible{INVALID_DATE} = 1 if ($invalidduedate); + #$issuingimpossible{INVALID_DATE} = 1 unless ($duedate); # # BORROWER STATUS @@ -687,7 +693,7 @@ sub CanBookBeIssued { # DEBTS my ($amount) = - GetMemberAccountRecords( $borrower->{'borrowernumber'}, $duedate ); + C4::Members::GetMemberAccountRecords( $borrower->{'borrowernumber'}, '' && $duedate->output('iso') ); if ( C4::Context->preference("IssuingInProcess") ) { my $amountlimit = C4::Context->preference("noissuescharge"); if ( $amount > $amountlimit && !$inprocess ) { @@ -706,7 +712,7 @@ sub CanBookBeIssued { # # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS # - my $toomany = TooMany( $borrower, $item->{biblionumber} ); + my $toomany = TooMany( $borrower, $item->{biblionumber}, $item ); $needsconfirmation{TOO_MANY} = $toomany if $toomany; # @@ -720,6 +726,22 @@ sub CanBookBeIssued { { $issuingimpossible{NOT_FOR_LOAN} = 1; } + elsif ( !$item->{'notforloan'} ){ + # we have to check itemtypes.notforloan also + if (C4::Context->preference('item-level_itypes')){ + # this should probably be a subroutine + my $sth = $dbh->prepare("SELECT notforloan FROM itemtypes WHERE itemtype = ?"); + $sth->execute($item->{'itemtype'}); + my $notforloan=$sth->fetchrow_hashref(); + $sth->finish(); + if ($notforloan->{'notforloan'} == 1){ + $issuingimpossible{NOT_FOR_LOAN} = 1; + } + } + elsif ($biblioitem->{'notforloan'} == 1){ + $issuingimpossible{NOT_FOR_LOAN} = 1; + } + } if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) { $issuingimpossible{WTHDRAWN} = 1; @@ -733,7 +755,7 @@ sub CanBookBeIssued { my $userenv = C4::Context->userenv; if ( ($userenv) && ( $userenv->{flags} != 1 ) ) { $issuingimpossible{NOTSAMEBRANCH} = 1 - if ( $item->{'holdingbranch'} ne $userenv->{branch} ); + if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} ); } } @@ -745,7 +767,7 @@ sub CanBookBeIssued { # Already issued to current borrower. Ask whether the loan should # be renewed. - my ($CanBookBeRenewed) = CanBookBeRenewed( + my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed( $borrower->{'borrowernumber'}, $item->{'itemnumber'} ); @@ -767,46 +789,32 @@ sub CanBookBeIssued { } # See if the item is on reserve. - my ( $restype, $res ) = CheckReserves( $item->{'itemnumber'} ); + my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->{'itemnumber'} ); if ($restype) { - my $resbor = $res->{'borrowernumber'}; + my $resbor = $res->{'borrowernumber'}; + my ( $resborrower, $flags ) = 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. - my ( $resborrower, $flags ) = - GetMemberDetails( $resbor, 0 ); - my $branches = GetBranches(); - my $branchname = - $branches->{ $res->{'branchcode'} }->{'branchname'}; $needsconfirmation{RESERVE_WAITING} = "$resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}, $branchname)"; - -# CancelReserve(0, $res->{'itemnumber'}, $res->{'borrowernumber'}); Doesn't belong in a checking subroutine. } elsif ( $restype eq "Reserved" ) { - # The item is on reserve for someone else. - my ( $resborrower, $flags ) = - GetMemberDetails( $resbor, 0 ); - my $branches = GetBranches(); - my $branchname = - $branches->{ $res->{'branchcode'} }->{'branchname'}; $needsconfirmation{RESERVED} = "$res->{'reservedate'} : $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'})"; } } if ( C4::Context->preference("LibraryName") eq "Horowhenua Library Trust" ) { if ( $borrower->{'categorycode'} eq 'W' ) { - my %issuingimpossible; - return ( \%issuingimpossible, \%needsconfirmation ); - } else { - return ( \%issuingimpossible, \%needsconfirmation ); + my %emptyhash; + return ( \%emptyhash, \%needsconfirmation ); } - } else { - return ( \%issuingimpossible, \%needsconfirmation ); - } + } + return ( \%issuingimpossible, \%needsconfirmation ); } =head2 AddIssue @@ -843,105 +851,102 @@ AddIssue does the following things : sub AddIssue { my ( $borrower, $barcode, $date, $cancelreserve ) = @_; my $dbh = C4::Context->dbh; -my $barcodecheck=CheckValidBarcode($barcode); -if ($borrower and $barcode and $barcodecheck ne '0'){ -# my ($borrower, $flags) = &GetMemberDetails($borrowernumber, 0); - # find which item we issue - my $item = GetItem('', $barcode); - - # get actual issuing if there is one - my $actualissue = GetItemIssue( $item->{itemnumber}); - - # get biblioinformation for this item - my $biblio = GetBiblioFromItemNumber($item->{itemnumber}); - - # - # check if we just renew the issue. - # - if ( $actualissue->{borrowernumber} eq $borrower->{'borrowernumber'} ) { - # we renew, do we need to add some charge ? - my ( $charge, $itemtype ) = GetIssuingCharges( - $item->{'itemnumber'}, - $borrower->{'borrowernumber'} - ); - if ( $charge > 0 ) { - AddIssuingCharge( - $item->{'itemnumber'}, - $borrower->{'borrowernumber'}, $charge - ); - $item->{'charge'} = $charge; - } - &UpdateStats( - C4::Context->userenv->{'branch'}, - 'renew', $charge, - '', $item->{'itemnumber'}, - $biblio->{'itemtype'}, $borrower->{'borrowernumber'} - ); - AddRenewal( - $borrower->{'borrowernumber'}, - $item->{'itemnumber'} - ); - } - else {# it's NOT a renewal - if ( $actualissue->{borrowernumber}) { - # This book is currently on loan, but not to the person - # who wants to borrow it now. mark it returned before issuing to the new borrower - AddReturn( - $item->{'barcode'}, - C4::Context->userenv->{'branch'} - ); - } + my $barcodecheck=CheckValidBarcode($barcode); + if ($borrower and $barcode and $barcodecheck ne '0'){ + # find which item we issue + my $item = GetItem('', $barcode); + my $datedue; + + my $branch; + # Get which branchcode we need + if (C4::Context->preference('CircControl') eq 'PickupLibary'){ + $branch = C4::Context->userenv->{'branchcode'}; + } + elsif (C4::Context->preference('CircControl') eq 'PatronLibary'){ + $branch = $borrower->{'branchcode'}; + } + else { + # items home library + $branch = $item->{'homebranch'}; + } + + # get actual issuing if there is one + my $actualissue = GetItemIssue( $item->{itemnumber}); + + # get biblioinformation for this item + my $biblio = GetBiblioFromItemNumber($item->{itemnumber}); + + # + # check if we just renew the issue. + # + if ( $actualissue->{borrowernumber} eq $borrower->{'borrowernumber'} ) { + AddRenewal( + $borrower->{'borrowernumber'}, + $item->{'itemnumber'}, + $branch, + $date + ); - # See if the item is on reserve. - my ( $restype, $res ) = - CheckReserves( $item->{'itemnumber'} ); - if ($restype) { - my $resbor = $res->{'borrowernumber'}; - if ( $resbor eq $borrower->{'borrowernumber'} ) { + } + else { + # it's NOT a renewal + if ( $actualissue->{borrowernumber}) { + # This book is currently on loan, but not to the person + # who wants to borrow it now. mark it returned before issuing to the new borrower + AddReturn( + $item->{'barcode'}, + C4::Context->userenv->{'branch'} + ); + } - # 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. - my ( $resborrower, $flags ) = GetMemberDetails( $resbor, 0 ); - my $branches = GetBranches(); - my $branchname = - $branches->{ $res->{'branchcode'} }->{'branchname'}; - } - elsif ( $restype eq "Reserved" ) { - - # warn "Reserved"; - # The item is reserved by someone else. - my ( $resborrower, $flags ) = - GetMemberDetails( $resbor, 0 ); - my $branches = GetBranches(); - my $branchname = - $branches->{ $res->{'branchcode'} }->{'branchname'}; - if ($cancelreserve) { # cancel reserves on this item - CancelReserve( 0, $res->{'itemnumber'}, - $res->{'borrowernumber'} ); - } - } - if ($cancelreserve) { - CancelReserve( $res->{'biblionumber'}, 0, + # 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. + my ( $resborrower, $flags ) = GetMemberDetails( $resbor, 0 ); + my $branches = GetBranches(); + my $branchname = + $branches->{ $res->{'branchcode'} }->{'branchname'}; + } + elsif ( $restype eq "Reserved" ) { + + # warn "Reserved"; + # The item is reserved by someone else. + my ( $resborrower, $flags ) = + GetMemberDetails( $resbor, 0 ); + my $branches = GetBranches(); + my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'}; + 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'} - ); - } - } + } + else { + # set waiting reserve to first in reserve queue as book isn't waiting now + ModReserve(1, + $res->{'biblionumber'}, + $res->{'borrowernumber'}, + $res->{'branchcode'} + ); + } + } - # Starting process for transfer job (checking transfert and validate it if we have one) + # Starting process for transfer job (checking transfert and validate it if we have one) my ($datesent) = GetTransfers($item->{'itemnumber'}); if ($datesent) { # updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for lisibility of this case (maybe for stats ....) @@ -964,42 +969,41 @@ if ($borrower and $barcode and $barcodecheck ne '0'){ (borrowernumber, itemnumber,issuedate, date_due, branchcode) VALUES (?,?,?,?,?)" ); - my $loanlength = GetLoanLength( - $borrower->{'categorycode'}, - $biblio->{'itemtype'}, - $borrower->{'branchcode'} - ); - my $datedue = time + ($loanlength) * 86400; - my @datearr = localtime($datedue); - my $dateduef = - sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]); + my $dateduef; if ($date) { $dateduef = $date; - } - $dateduef=CheckValidDatedue($dateduef,$item->{'itemnumber'},C4::Context->userenv->{'branch'}); - # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate - if ( C4::Context->preference('ReturnBeforeExpiry') - && $dateduef gt $borrower->{dateexpiry} ) - { - $dateduef = $borrower->{dateexpiry}; - } - $sth->execute( + } else { + my $itype=(C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} ; + my $loanlength = GetLoanLength( + $borrower->{'categorycode'}, + $itype, + $branch + ); + $datedue = time + ($loanlength) * 86400; + my @datearr = localtime($datedue); + $dateduef = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso'); + $dateduef=CheckValidDatedue($dateduef,$item->{'itemnumber'},C4::Context->userenv->{'branch'}); + + # if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate + if ( C4::Context->preference('ReturnBeforeExpiry') && $dateduef->output('iso') gt $borrower->{dateexpiry} ) { + $dateduef = C4::Dates->new($borrower->{dateexpiry},'iso'); + } + }; + $sth->execute( $borrower->{'borrowernumber'}, $item->{'itemnumber'}, - strftime( "%Y-%m-%d", localtime ),$dateduef, C4::Context->userenv->{'branch'} + strftime( "%Y-%m-%d", localtime ),$dateduef->output('iso'), C4::Context->userenv->{'branch'} ); $sth->finish; $item->{'issues'}++; - $sth = - $dbh->prepare( - "UPDATE items SET issues=?, holdingbranch=?, itemlost=0, datelastborrowed = now() WHERE itemnumber=?"); - $sth->execute( - $item->{'issues'}, - C4::Context->userenv->{'branch'}, - $item->{'itemnumber'} - ); - $sth->finish; - &ModDateLastSeen( $item->{'itemnumber'} ); + ModItem({ issues => $item->{'issues'}, + holdingbranch => C4::Context->userenv->{'branch'}, + itemlost => 0, + datelastborrowed => C4::Dates->new()->output('iso'), + onloan => $dateduef->output('iso'), + }, $item->{'biblionumber'}, $item->{'itemnumber'}); + ModDateLastSeen( $item->{'itemnumber'} ); + # If it costs to borrow this book, charge it to the patron's account. my ( $charge, $itemtype ) = GetIssuingCharges( $item->{'itemnumber'}, @@ -1024,7 +1028,8 @@ if ($borrower and $barcode and $barcodecheck ne '0'){ &logaction(C4::Context->userenv->{'number'},"CIRCULATION","ISSUE",$borrower->{'borrowernumber'},$biblio->{'biblionumber'}) if C4::Context->preference("IssueLog"); - } + return ($datedue); + } } =head2 GetLoanLength @@ -1040,9 +1045,9 @@ sub GetLoanLength { my $dbh = C4::Context->dbh; my $sth = $dbh->prepare( -"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=?" +"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 ); @@ -1050,7 +1055,7 @@ sub GetLoanLength { return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; - $sth->execute( $borrowertype, $itemtype, "" ); + $sth->execute( $borrowertype, $itemtype, "*" ); $loanlength = $sth->fetchrow_hashref; return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; @@ -1065,7 +1070,7 @@ sub GetLoanLength { return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; - $sth->execute( $borrowertype, "*", "" ); + $sth->execute( $borrowertype, "*", "*" ); $loanlength = $sth->fetchrow_hashref; return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; @@ -1075,12 +1080,12 @@ sub GetLoanLength { return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; - $sth->execute( "*", $itemtype, "" ); + $sth->execute( "*", $itemtype, "*" ); $loanlength = $sth->fetchrow_hashref; return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; - $sth->execute( "*", "*", "" ); + $sth->execute( "*", "*", "*" ); $loanlength = $sth->fetchrow_hashref; return $loanlength->{issuelength} if defined($loanlength) && $loanlength->{issuelength} ne 'NULL'; @@ -1092,12 +1097,13 @@ sub GetLoanLength { =head2 AddReturn ($doreturn, $messages, $iteminformation, $borrower) = - &AddReturn($barcode, $branch); + &AddReturn($barcode, $branch, $exemptfine); Returns a book. C<$barcode> is the bar code of the book being returned. C<$branch> is -the code of the branch where the book is being returned. +the code of the branch where the book is being returned. C<$exemptfine> +indicates that overdue charges for the item will not be applied. C<&AddReturn> returns a list of four items: @@ -1140,7 +1146,7 @@ patron who last borrowed the book. =cut sub AddReturn { - my ( $barcode, $branch ) = @_; + my ( $barcode, $branch, $exemptfine ) = @_; my $dbh = C4::Context->dbh; my $messages; my $doreturn = 1; @@ -1150,6 +1156,8 @@ sub AddReturn { # get information on item my $iteminformation = GetItemIssue( GetItemnumberFromBarcode($barcode)); + my $biblio = GetBiblioItemData($iteminformation->{'biblioitemnumber'}); +# use Data::Dumper;warn Data::Dumper::Dumper($iteminformation); unless ($iteminformation->{'itemnumber'} ) { $messages->{'BadBarcode'} = $barcode; $doreturn = 0; @@ -1166,7 +1174,13 @@ sub AddReturn { if ( $hbr && $branches->{$hbr}->{'PE'} ) { $messages->{'IsPermanent'} = $hbr; } - + + # if independent branches are on and returning to different branch, refuse the return + if ($hbr ne C4::Context->userenv->{'branch'} && C4::Context->preference("IndependantBranches")){ + $messages->{'Wrongbranch'} = 1; + $doreturn=0; + } + # check that the book has been cancelled if ( $iteminformation->{'wthdrawn'} ) { $messages->{'wthdrawn'} = 1; @@ -1192,16 +1206,18 @@ sub AddReturn { # continue to deal with returns cases, but not only if we have an issue - # the holdingbranch is updated if the document is returned in an other location . - if ( $iteminformation->{'holdingbranch'} ne C4::Context->userenv->{'branch'} ) - { - UpdateHoldingbranch(C4::Context->userenv->{'branch'},$iteminformation->{'itemnumber'}); - # reload iteminformation holdingbranch with the userenv value - $iteminformation->{'holdingbranch'} = C4::Context->userenv->{'branch'}; - } + # the holdingbranch is updated if the document is returned in an other location . + if ( $iteminformation->{'holdingbranch'} ne C4::Context->userenv->{'branch'} ) { + UpdateHoldingbranch(C4::Context->userenv->{'branch'},$iteminformation->{'itemnumber'}); + # reload iteminformation holdingbranch with the userenv value + $iteminformation->{'holdingbranch'} = C4::Context->userenv->{'branch'}; + } ModDateLastSeen( $iteminformation->{'itemnumber'} ); - ($borrower) = C4::Members::GetMemberDetails( $iteminformation->{borrowernumber}, 0 ); - + ModItem({ onloan => undef }, $biblio->{'biblionumber'}, $iteminformation->{'itemnumber'}); + + if ($iteminformation->{borrowernumber}){ + ($borrower) = C4::Members::GetMemberDetails( $iteminformation->{borrowernumber}, 0 ); + } # fix up the accounts..... if ( $iteminformation->{'itemlost'} ) { $messages->{'WasLost'} = 1; @@ -1238,7 +1254,7 @@ sub AddReturn { } # fix up the overdues in accounts... FixOverduesOnReturn( $borrower->{'borrowernumber'}, - $iteminformation->{'itemnumber'} ); + $iteminformation->{'itemnumber'}, $exemptfine ); # find reserves..... # if we don't have a reserve with the status W, we launch the Checkreserves routine @@ -1255,7 +1271,7 @@ sub AddReturn { UpdateStats( $branch, 'return', '0', '', $iteminformation->{'itemnumber'}, - $iteminformation->{'itemtype'}, + $biblio->{'itemtype'}, $borrower->{'borrowernumber'} ); @@ -1266,11 +1282,13 @@ sub AddReturn { #we check, if we don't have reserv or transfert for this document, if not, return it to homebranch . if ( ($iteminformation->{'holdingbranch'} ne $iteminformation->{'homebranch'}) and not $messages->{'WrongTransfer'} and ($validTransfert ne 1) and ($reserveDone ne 1) ){ - if (C4::Context->preference("AutomaticItemReturn") == 1) { - ModItemTransfer($iteminformation->{'itemnumber'}, C4::Context->userenv->{'branch'}, $iteminformation->{'homebranch'}); - $messages->{'WasTransfered'} = 1; - warn "was transfered"; - } + if (C4::Context->preference("AutomaticItemReturn") == 1) { + ModItemTransfer($iteminformation->{'itemnumber'}, C4::Context->userenv->{'branch'}, $iteminformation->{'homebranch'}); + $messages->{'WasTransfered'} = 1; + } + else { + $messages->{'NeedsTransfer'} = 1; + } } } return ( $doreturn, $messages, $iteminformation, $borrower ); @@ -1278,7 +1296,7 @@ sub AddReturn { =head2 FixOverduesOnReturn - &FixOverduesOnReturn($brn,$itm); + &FixOverduesOnReturn($brn,$itm, $exemptfine); C<$brn> borrowernumber @@ -1289,7 +1307,7 @@ internal function, called only by AddReturn =cut sub FixOverduesOnReturn { - my ( $borrowernumber, $item ) = @_; + my ( $borrowernumber, $item, $exemptfine ) = @_; my $dbh = C4::Context->dbh; # check for overdue fine @@ -1300,14 +1318,15 @@ sub FixOverduesOnReturn { $sth->execute( $borrowernumber, $item ); # alter fine to show that the book has been returned - if ( my $data = $sth->fetchrow_hashref ) { - my $usth = - $dbh->prepare( -"UPDATE accountlines SET accounttype='F' WHERE (borrowernumber = ?) AND (itemnumber = ?) AND (accountno = ?)" - ); - $usth->execute( $borrowernumber, $item, $data->{'accountno'} ); + my $data; + if ($data = $sth->fetchrow_hashref) { + my $uquery =($exemptfine)? "update accountlines set accounttype='FFOR', amountoutstanding=0":"update accountlines set accounttype='F' "; + $uquery .= " where (borrowernumber = ?) and (itemnumber = ?) and (accountno = ?)"; + my $usth = $dbh->prepare($uquery); + $usth->execute($borrowernumber,$item ,$data->{'accountno'}); $usth->finish(); } + $sth->finish(); return; } @@ -1390,7 +1409,7 @@ sub FixAccountForLostAndReturned { if ($amountleft > 0){ $amountleft*=-1; } - my $desc="Book Returned ".$iteminfo->{'barcode'}; + my $desc="Item Returned ".$iteminfo->{'barcode'}; $usth = $dbh->prepare("INSERT INTO accountlines (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding) VALUES (?,?,now(),?,?,'CR',?)"); @@ -1401,9 +1420,7 @@ sub FixAccountForLostAndReturned { VALUES (?,?,?,?)"); $usth->execute($borrower->{'borrowernumber'},$data->{'accountno'},$nextaccntno,$offset); $usth->finish; - $usth = $dbh->prepare("UPDATE items SET paidfor='' WHERE itemnumber=?"); - $usth->execute($itm); - $usth->finish; + ModItem({ paidfor => '' }, undef, $itm); } $sth->finish; return; @@ -1418,6 +1435,7 @@ Returns patrons currently having a book. nothing if item is not issued atm C<$itemnumber> is the itemnumber Returns an array of hashes + =cut sub GetItemIssue { @@ -1456,6 +1474,7 @@ C<$itemnumber> is the itemnumber C<$history> is 0 if you want actuel "issuer" (if it exist) and 1 if you want issues history Returns an array of hashes + =cut sub GetItemIssues { @@ -1468,8 +1487,10 @@ sub GetItemIssues { my $sth = $dbh->prepare( "SELECT * FROM issues + LEFT JOIN borrowers ON borrowers.borrowernumber + LEFT JOIN items ON items.itemnumber=issues.itemnumber WHERE - itemnumber=?".($history?"":" AND returndate IS NULL "). + issues.itemnumber=?".($history?"":" AND returndate IS NULL "). "ORDER BY issues.date_due DESC" ); $sth->execute($itemnumber); @@ -1480,7 +1501,6 @@ sub GetItemIssues { $data->{'overdue'} = 1; } my $itemnumber = $data->{'itemnumber'}; - push @GetItemIssues, $data; } $sth->finish; @@ -1504,7 +1524,7 @@ sub GetBiblioIssues { return undef unless $biblionumber; my $dbh = C4::Context->dbh; my $query = " - SELECT issues.*,biblio.biblionumber,biblio.title, biblio.author,borrowers.cardnumber,borrowers.surname,borrowers.firstname + SELECT issues.*,items.barcode,biblio.biblionumber,biblio.title, biblio.author,borrowers.cardnumber,borrowers.surname,borrowers.firstname FROM issues LEFT JOIN borrowers ON borrowers.borrowernumber = issues.borrowernumber LEFT JOIN items ON issues.itemnumber = items.itemnumber @@ -1525,7 +1545,7 @@ sub GetBiblioIssues { =head2 CanBookBeRenewed -$ok = &CanBookBeRenewed($borrowernumber, $itemnumber); +($ok,$error) = &CanBookBeRenewed($borrowernumber, $itemnumber); Find out whether a borrowed item may be renewed. @@ -1539,7 +1559,7 @@ C<$itemnumber> is the number of the item to renew. C<$CanBookBeRenewed> returns a true value iff the item may be renewed. The item must currently be on loan to the specified borrower; renewals must be allowed for the item's type; and the borrower must not have -already renewed the loan. +already renewed the loan. $error will contain the reason the renewal can not proceed =cut @@ -1550,6 +1570,7 @@ sub CanBookBeRenewed { my $dbh = C4::Context->dbh; my $renews = 1; my $renewokay = 0; + my $error; # Look in the issues table for this item, lent to this borrower, # and not yet returned. @@ -1581,18 +1602,22 @@ sub CanBookBeRenewed { if ( my $data2 = $sth2->fetchrow_hashref ) { $renews = $data2->{'renewalsallowed'}; } - if ( $renews && $renews >= $data1->{'renewals'} ) { + if ( $renews && $renews > $data1->{'renewals'} ) { $renewokay = 1; } + else { + $error="too_many"; + } $sth2->finish; my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber); if ($resfound) { $renewokay = 0; + $error="on_reserve" } } $sth1->finish; - return ($renewokay); + return ($renewokay,$error); } =head2 AddRenewal @@ -1617,22 +1642,27 @@ sub AddRenewal { my ( $borrowernumber, $itemnumber, $branch ,$datedue ) = @_; my $dbh = C4::Context->dbh; - + my $biblio = GetBiblioFromItemNumber($itemnumber); # If the due date wasn't specified, calculate it by adding the # book's loan length to today's date. - if ( $datedue eq "" ) { + unless ( $datedue ) { + - my $biblio = GetBiblioFromItemNumber($itemnumber); - my $borrower = GetMemberDetails( $borrowernumber, 0 ); + my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ); my $loanlength = GetLoanLength( $borrower->{'categorycode'}, - $biblio->{'itemtype'}, - $borrower->{'branchcode'} + (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} , + $borrower->{'branchcode'} ); - my ( $due_year, $due_month, $due_day ) = - Add_Delta_DHMS( Today_and_Now(), $loanlength, 0, 0, 0 ); - $datedue = "$due_year-$due_month-$due_day"; - $datedue=CheckValidDatedue($datedue,$itemnumber,$branch); + #FIXME -- choose issuer or borrower branch. + #FIXME -- where's the calendar ? + #FIXME -- $debug-ify the (0) + my @darray = Add_Delta_DHMS( Today_and_Now(), $loanlength, 0, 0, 0 ); + $datedue = C4::Dates->new( sprintf("%04d-%02d-%02d",@darray[0..2]), 'iso'); + (0) and print STDERR "C4::Dates->new->output = " . C4::Dates->new()->output() + . "\ndatedue->output = " . $datedue->output() + . "\n(Y,M,D) = " . join ',', @darray; + $datedue=CheckValidDatedue($datedue,$itemnumber,$branch); } # Find the issues record for this book @@ -1654,11 +1684,12 @@ sub AddRenewal { AND itemnumber=? AND returndate IS NULL" ); - $sth->execute( $datedue, $renews, $borrowernumber, $itemnumber ); + $sth->execute( $datedue->output('iso'), $renews, $borrowernumber, $itemnumber ); $sth->finish; - # Log the renewal - UpdateStats( C4::Context->userenv->{'branchcode'}, 'renew', '', '', $itemnumber ); + # Update the renewal count on the item, and tell zebra to reindex + $renews = $biblio->{'renewals'} + 1; + ModItem({ renewals => $renews }, $biblio->{'biblionumber'}, $itemnumber); # Charge a new rental fee, if applicable? my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber ); @@ -1677,8 +1708,39 @@ sub AddRenewal { 'Rent', $charge, $itemnumber ); $sth->finish; } + # Log the renewal + UpdateStats( $branch, 'renew', $charge, '', $itemnumber ); } +sub GetRenewCount { + # check renewal status + my ($bornum,$itemno)=@_; + my $dbh = C4::Context->dbh; + my $renewcount = 0; + my $renewsallowed = 0; + my $renewsleft = 0; + # Look in the issues table for this item, lent to this borrower, + # and not yet returned. + + # FIXME - I think this function could be redone to use only one SQL call. + my $sth = $dbh->prepare("select * from issues + where (borrowernumber = ?) + and (itemnumber = ?) + and returndate is null"); + $sth->execute($bornum,$itemno); + my $data = $sth->fetchrow_hashref; + $renewcount = $data->{'renewals'} if $data->{'renewals'}; + my $sth2 = $dbh->prepare("select renewalsallowed from items,biblioitems,itemtypes + where (items.itemnumber = ?) + and (items.biblioitemnumber = biblioitems.biblioitemnumber) + and (biblioitems.itemtype = itemtypes.itemtype)"); + $sth2->execute($itemno); + my $data2 = $sth2->fetchrow_hashref(); + $renewsallowed = $data2->{'renewalsallowed'}; + $renewsleft = $renewsallowed - $renewcount; +# warn "Renewcount:$renewcount RenewsAll:$renewsallowed RenewLeft:$renewsleft"; + return ($renewcount,$renewsallowed,$renewsleft); +} =head2 GetIssuingCharges ($charge, $item_type) = &GetIssuingCharges($itemnumber, $borrowernumber); @@ -1705,13 +1767,15 @@ sub GetIssuingCharges { my $item_type; # Get the book's item type and rental charge (via its biblioitem). - my $sth1 = $dbh->prepare( - "SELECT itemtypes.itemtype,rentalcharge FROM items - LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber - LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype - WHERE items.itemnumber =? - " - ); + my $qcharge = "SELECT itemtypes.itemtype,rentalcharge FROM items + LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber"; + $qcharge .= (C4::Context->preference('item-level_itypes')) + ? " LEFT JOIN itemtypes ON items.itype = itemtypes.itemtype " + : " LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype "; + + $qcharge .= "WHERE items.itemnumber =?"; + + my $sth1 = $dbh->prepare($qcharge); $sth1->execute($itemnumber); if ( my $data1 = $sth1->fetchrow_hashref ) { $item_type = $data1->{'itemtype'}; @@ -1889,21 +1953,14 @@ sub updateWrongTransfer { $items = UpdateHoldingbranch($branch,$itmenumber); Simple methode for updating hodlingbranch in items BDD line + =cut sub UpdateHoldingbranch { - my ( $branch,$itmenumber ) = @_; - my $dbh = C4::Context->dbh; -# first step validate the actual line of transfert . - my $sth = - $dbh->prepare( - "update items set holdingbranch = ? where itemnumber= ?" - ); - $sth->execute($branch,$itmenumber); - $sth->finish; - - + my ( $branch,$itemnumber ) = @_; + ModItem({ holdingbranch => $branch }, undef, $itemnumber); } + =head2 CheckValidDatedue $newdatedue = CheckValidDatedue($date_due,$itemnumber,$branchcode); @@ -1911,13 +1968,18 @@ this function return a new date due after checked if it's a repeatable or specia C<$date_due> = returndate calculate with no day check C<$itemnumber> = itemnumber C<$branchcode> = localisation of issue + =cut -sub CheckValidDatedue{ + +# Why not create calendar object? - +# TODO add 'duedate' option to useDaysMode . +sub CheckValidDatedue { my ($date_due,$itemnumber,$branchcode)=@_; -my @datedue=split('-',$date_due); +my @datedue=split('-',$date_due->output('iso')); my $years=$datedue[0]; my $month=$datedue[1]; my $day=$datedue[2]; +# die "Item# $itemnumber ($branchcode) due: " . ${date_due}->output() . "\n(Y,M,D) = ($years,$month,$day)": my $dow; for (my $i=0;$i<2;$i++){ $dow=Day_of_Week($years,$month,$day); @@ -1930,9 +1992,10 @@ for (my $i=0;$i<2;$i++){ (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1'); } } -my $newdatedue=$years."-".$month."-".$day; + my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso'); return $newdatedue; } + =head2 CheckRepeatableHolidays $countrepeatable = CheckRepeatableHoliday($itemnumber,$week_day,$branchcode); @@ -1967,7 +2030,9 @@ C<$month> = the month of datedue C<$day> = the day of datedue C<$itemnumber> = itemnumber C<$branchcode> = localisation of issue + =cut + sub CheckSpecialHolidays{ my ($years,$month,$day,$itemnumber,$branchcode) = @_; my $dbh = C4::Context->dbh; @@ -1993,7 +2058,9 @@ C<$month> = the month of datedue C<$day> = the day of datedue C<$itemnumber> = itemnumber C<$branchcode> = localisation of issue + =cut + sub CheckRepeatableSpecialHolidays{ my ($month,$day,$itemnumber,$branchcode) = @_; my $dbh = C4::Context->dbh;