package C4::Overdues;
-# $Id$
# Copyright 2000-2002 Katipo Communications
#
# Suite 330, Boston, MA 02111-1307 USA
use strict;
-require Exporter;
-use C4::Context;
use Date::Calc qw/Today/;
-use vars qw($VERSION @ISA @EXPORT);
-use C4::Accounts;
use Date::Manip qw/UnixDate/;
+use C4::Context;
+use C4::Accounts;
use C4::Log; # logaction
-# set the version for version checking
-$VERSION = do { my @v = '$Revision$' =~ /\d+/g;
-shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
-
-=head1 NAME
-
-C4::Circulation::Fines - Koha module dealing with fines
-
-=head1 SYNOPSIS
-
- use C4::Overdues;
-
-=head1 DESCRIPTION
-
-This module contains several functions for dealing with fines for
-overdue items. It is primarily used by the 'misc/fines2.pl' script.
-
-=head1 FUNCTIONS
-
-=over 2
-
-=cut
+use vars qw($VERSION @ISA @EXPORT);
-@ISA = qw(Exporter);
-# subs to rename (and maybe merge some...)
-push @EXPORT, qw(
+BEGIN {
+ # set the version for version checking
+ $VERSION = 3.01;
+ require Exporter;
+ @ISA = qw(Exporter);
+ # subs to rename (and maybe merge some...)
+ push @EXPORT, qw(
&CalcFine
&Getoverdues
&checkoverdues
&GetOverduesForBranch
&RemoveNotifyLine
&AddNotifyLine
-);
-# subs to remove
-push @EXPORT, qw(
+ );
+ # subs to remove
+ push @EXPORT, qw(
&BorType
-);
+ );
-#
-# All subs to move : check that an equivalent don't exist already before moving
-#
+ # check that an equivalent don't exist already before moving
-# subs to move to Circulation.pm
-push @EXPORT, qw(
+ # subs to move to Circulation.pm
+ push @EXPORT, qw(
&GetIssuingRules
&GetIssuesIteminfo
-);
-# subs to move to Members.pm
-push @EXPORT, qw(
+ );
+ # subs to move to Members.pm
+ push @EXPORT, qw(
&CheckBorrowerDebarred
&UpdateBorrowerDebarred
-);
-# subs to move to Biblio.pm
-push @EXPORT, qw(
+ );
+ # subs to move to Biblio.pm
+ push @EXPORT, qw(
&GetItems
&ReplacementCost
-);
+ );
+}
-=item Getoverdues
+=head1 NAME
+
+C4::Circulation::Fines - Koha module dealing with fines
+
+=head1 SYNOPSIS
+
+ use C4::Overdues;
- ($count, $overdues) = &Getoverdues();
+=head1 DESCRIPTION
-Returns the list of all overdue books.
+This module contains several functions for dealing with fines for
+overdue items. It is primarily used by the 'misc/fines2.pl' script.
-C<$count> is the number of elements in C<@{$overdues}>.
+=head1 FUNCTIONS
+
+=over 2
+
+=item Getoverdues
+
+ ($overdues) = &Getoverdues();
+
+Returns the list of all overdue books, with their itemtype.
C<$overdues> is a reference-to-array. Each element is a
reference-to-hash whose keys are the fields of the issues table in the
#'
sub Getoverdues {
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare(
- "Select * from issues where date_due < now() and returndate is
- NULL order by borrowernumber "
- );
+ my $sth = (C4::context->preference('item-level_itypes')) ?
+ $dbh->prepare(
+ "SELECT issues.*,items.itype as itemtype FROM issues
+ LEFT JOIN items USING (itemnumber)
+ WHERE date_due < now()
+ AND returndate IS NULL ORDER BY borrowernumber " )
+ :
+ $dbh->prepare(
+ "SELECT issues.*,biblioitems.itemtype,items.itype FROM issues
+ LEFT JOIN items USING (itemnumber)
+ LEFT JOIN biblioitems USING (biblioitemnumber)
+ WHERE date_due < now()
+ AND returndate IS
+ NULL ORDER BY borrowernumber " );
$sth->execute;
my @results;
my @overdueitems;
my $count = 0;
my $sth = $dbh->prepare(
- "SELECT * FROM issues,biblio,biblioitems,items
- WHERE items.biblioitemnumber = biblioitems.biblioitemnumber
- AND items.biblionumber = biblio.biblionumber
- AND issues.itemnumber = items.itemnumber
- AND issues.borrowernumber = ?
+ "SELECT * FROM issues
+ LEFT JOIN items ON issues.itemnumber = items.itemnumber
+ LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
+ LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
+ WHERE issues.borrowernumber = ?
AND issues.returndate is NULL
AND issues.date_due < ?"
);
#'
sub CalcFine {
- my ( $itemnumber, $bortype, $difference , $dues ) = @_;
+ my ( $item, $bortype, $difference , $dues ) = @_;
my $dbh = C4::Context->dbh;
- my $data = GetIssuingRules($itemnumber,$bortype);
my $amount = 0;
my $printout;
- my $countspecialday=&GetSpecialHolidays($dues,$itemnumber);
- my $countrepeatableday=&GetRepeatableHolidays($dues,$itemnumber,$difference);
+ # calculate how many days the patron is late
+ my $countspecialday=&GetSpecialHolidays($dues,$item->{itemnumber});
+ my $countrepeatableday=&GetRepeatableHolidays($dues,$item->{itemnumber},$difference);
my $countalldayclosed = $countspecialday + $countrepeatableday;
- my $daycount = $difference - $countalldayclosed;
+ my $daycount = $difference - $countalldayclosed;
+ # get issuingrules (fines part will be used)
+ my $data = GetIssuingRules($item->{'itemtype'},$bortype);
my $daycounttotal = $daycount - $data->{'firstremind'};
+ if ($data->{'chargeperiod'} >0) { # if there is a rule for this bortype
if ($data->{'firstremind'} < $daycount)
- {
- $amount = $daycounttotal*$data->{'fine'};
+ {
+ $amount = int($daycounttotal/$data->{'chargeperiod'})*$data->{'fine'};
+ }
+ } else {
+ # get fines default rules
+ my $data = GetIssuingRules($item->{'itemtype'},'*');
+ $daycounttotal = $daycount - $data->{'firstremind'};
+ if ($data->{'firstremind'} < $daycount)
+ {
+ if ($data->{'chargeperiod'} >0) { # if there is a rule for this bortype
+ $amount = int($daycounttotal/$data->{'chargeperiod'})*$data->{'fine'};
+ }
+ }
}
+
+ warn "Calc Fine for $item->{'itemnumber'}, $bortype, $difference , $dues = $amount / $daycount";
return ( $amount, $data->{'chargename'}, $printout ,$daycounttotal ,$daycount );
}
my $diff = $amount - $data->{'amount'};
my $out = $data->{'amountoutstanding'} + $diff;
my $sth2 = $dbh->prepare(
- "update accountlines set date=now(), amount=?,
- amountoutstanding=?,accounttype='FU' where
- borrowernumber=? and itemnumber=?
- and (accounttype='FU' or accounttype='O') and description like ?"
+ "UPDATE accountlines SET date=now(), amount=?,
+ amountoutstanding=?,accounttype='FU' WHERE
+ borrowernumber=? AND itemnumber=?
+ AND (accounttype='FU' OR accounttype='O') AND description LIKE ?"
);
$sth2->execute( $amount, $out, $data->{'borrowernumber'},
$data->{'itemnumber'}, "%$due%" );
# I think this else-clause deals with the case where we're adding
# a new fine.
my $sth4 = $dbh->prepare(
- "select title from biblio,items where items.itemnumber=?
- and biblio.biblionumber=items.biblionumber"
+ "SELECT title FROM biblio LEFT JOIN items ON biblio.biblionumber=items.biblionumber WHERE items.itemnumber=?"
);
$sth4->execute($itemnum);
my $title = $sth4->fetchrow_hashref;
# $sth3->finish;
# $accountno[0]++;
# begin transaction
- my $nextaccntno = getnextacctno($borrowernumber);
+ my $nextaccntno = C4::Accounts::getnextacctno($borrowernumber);
my $sth2 = $dbh->prepare(
- "Insert into accountlines
+ "INSERT INTO accountlines
(borrowernumber,itemnumber,date,amount,
- description,accounttype,amountoutstanding,accountno) values
+ description,accounttype,amountoutstanding,accountno) VALUES
(?,?,now(),?,?,'FU',?,?)"
);
$sth2->execute( $borrowernumber, $itemnum, $amount,
my ($borrowernumber) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare(
- "Select * from borrowers,categories where
- borrowernumber=? and
-borrowers.categorycode=categories.categorycode"
+ "SELECT * from borrowers
+ LEFT JOIN categories ON borrowers.categorycode=categories.categorycode
+ WHERE borrowernumber=?"
);
$sth->execute($borrowernumber);
my $data = $sth->fetchrow_hashref;
=item GetIssuingRules
-$data = &GetIssuingRules($itemnumber,$categorycode);
+$data = &GetIssuingRules($itemtype,$categorycode);
Looks up for all issuingrules an item info
=cut
sub GetIssuingRules {
- my ($itemnumber,$categorycode)=@_;
+ my ($itemtype,$categorycode)=@_;
my $dbh = C4::Context->dbh();
my $query=qq|SELECT *
- FROM items,biblioitems,itemtypes,issuingrules
- WHERE items.itemnumber=?
- AND items.biblioitemnumber=biblioitems.biblioitemnumber
- AND biblioitems.itemtype=itemtypes.itemtype
- AND issuingrules.itemtype=itemtypes.itemtype
- AND issuingrules.categorycode=?
- AND (items.itemlost <> 1
- OR items.itemlost is NULL)|;
+ FROM issuingrules
+ WHERE issuingrules.itemtype=?
+ AND issuingrules.categorycode=?
+ |;
my $sth = $dbh->prepare($query);
# print $query;
- $sth->execute($itemnumber,$categorycode);
+ $sth->execute($itemtype,$categorycode);
my ($data) = $sth->fetchrow_hashref;
$sth->finish;
return ($data);
}
-=item AmountNotify
+=item NumberNotifyId
-(@notify) = &AmountNotify($borrowernumber);
+(@notify) = &NumberNotifyId($borrowernumber);
Returns amount for all file per borrowers
C<@notify> array contains all file per borrowers
my @notify;
my $sth=$dbh->prepare($query);
$sth->execute($borrowernumber);
- while ( my $numberofotify=$sth->fetchrow_array){
- push (@notify,$numberofotify);
+ while ( my ($numberofnotify)=$sth->fetchrow){
+ push (@notify,$numberofnotify);
}
$sth->finish;
C<$totalnotify> contains amount of a file
-C<$notify_id> contains the file number for the borrower number nad item number
+C<$notify_id> contains the file number for the borrower number and item number
=cut
sub AmountNotify{
- my ($notifyid)=@_;
+ my ($notifyid,$borrowernumber)=@_;
my $dbh = C4::Context->dbh;
my $query=qq| SELECT sum(amountoutstanding)
FROM accountlines
- WHERE notify_id=?|;
+ WHERE notify_id=? AND borrowernumber = ?|;
my $sth=$dbh->prepare($query);
- $sth->execute($notifyid);
- my $totalnotify=$sth->fetchrow;
+ $sth->execute($notifyid,$borrowernumber);
+ my $totalnotify=$sth->fetchrow;
$sth->finish;
return ($totalnotify);
}
sub CheckExistantNotifyid {
my($borrowernumber,$date_due) = @_;
my $dbh = C4::Context->dbh;
- my $query = qq|SELECT notify_id FROM issues,accountlines
+ my $query = qq|SELECT notify_id FROM accountlines
+ LEFT JOIN issues ON issues.itemnumber= accountlines.itemnumber
WHERE accountlines.borrowernumber =?
- AND issues.itemnumber= accountlines.itemnumber
AND date_due = ?|;
my $sth=$dbh->prepare($query);
$sth->execute($borrowernumber,$date_due);
sub GetOverduesForBranch {
my ( $branch, $location) = @_;
+ my $itype_link = (C4::Context->preference('item-level_itypes')) ? " items.itype " : " biblioitems.itemtype ";
if ( not $location ) {
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("
accountlines.notify_level,
items.location,
accountlines.amountoutstanding
- FROM issues,borrowers,biblio,biblioitems,itemtypes,items,branches,accountlines
+ FROM accountlines
+ LEFT JOIN issues ON issues.itemnumber = accountlines.itemnumber AND issues.borrowernumber = accountlines.borrowernumber
+ LEFT JOIN borrowers ON borrowers.borrowernumber = accountlines.borrowernumber
+ LEFT JOIN items ON items.itemnumber = issues.itemnumber
+ LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber=items.biblioitemnumber
+ LEFT JOIN itemtypes ON itemtypes.itemtype = $itype_link
+ LEFT JOIN branches ON branches.branchcode = issues.branchcode
WHERE ( issues.returndate is null)
AND ( accountlines.amountoutstanding != '0.000000')
AND ( accountlines.accounttype = 'FU')
- AND ( issues.borrowernumber = accountlines.borrowernumber )
- AND ( issues.itemnumber = accountlines.itemnumber )
- AND ( borrowers.borrowernumber = issues.borrowernumber )
- AND ( biblio.biblionumber = biblioitems.biblionumber )
- AND ( biblioitems.biblionumber = items.biblionumber )
- AND ( itemtypes.itemtype = biblioitems.itemtype )
- AND ( items.itemnumber = issues.itemnumber )
- AND ( branches.branchcode = issues.branchcode )
AND (issues.branchcode = ?)
AND (issues.date_due <= NOW())
ORDER BY borrowers.surname
accountlines.notify_level,
items.location,
accountlines.amountoutstanding
- FROM issues,borrowers,biblio,biblioitems,itemtypes,items,branches,accountlines
+ FROM accountlines
+ LEFT JOIN issues ON issues.itemnumber = accountlines.itemnumber AND issues.borrowernumber = accountlines.borrowernumber
+ LEFT JOIN borrowers ON borrowers.borrowernumber = accountlines.borrowernumber
+ LEFT JOIN items ON items.itemnumber = issues.itemnumber
+ LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber=items.biblioitemnumber
+ LEFT JOIN itemtypes ON itemtypes.itemtype = $itype_link
+ LEFT JOIN branches ON branches.branchcode = issues.branchcode
WHERE ( issues.returndate is null )
AND ( accountlines.amountoutstanding != '0.000000')
AND ( accountlines.accounttype = 'FU')
- AND ( issues.borrowernumber = accountlines.borrowernumber )
- AND ( issues.itemnumber = accountlines.itemnumber )
- AND ( borrowers.borrowernumber = issues.borrowernumber )
- AND ( biblio.biblionumber = biblioitems.biblionumber )
- AND ( biblioitems.biblionumber = items.biblionumber )
- AND ( itemtypes.itemtype = biblioitems.itemtype )
- AND ( items.itemnumber = issues.itemnumber )
- AND ( branches.branchcode = issues.branchcode )
AND (issues.branchcode = ? AND items.location = ?)
AND (issues.date_due <= NOW())
ORDER BY borrowers.surname