From 9153e3d42529f7fee1589583ad1939ad5e6fae13 Mon Sep 17 00:00:00 2001 From: Ryan Higgins Date: Sun, 10 Aug 2008 07:24:03 -0500 Subject: [PATCH] Update fines cronjob: remove redundant scripts, remove some superfluous code in remaining fines.pl. Signed-off-by: Joshua Ferraro --- C4/Overdues.pm | 5 +- misc/cronjobs/fines-ll.pl | 195 ----------------------------------- misc/cronjobs/fines-sanop.pl | 194 ---------------------------------- misc/cronjobs/fines.pl | 110 ++++++++++++++++++++ misc/cronjobs/fines2.pl | 159 ---------------------------- 5 files changed, 114 insertions(+), 549 deletions(-) delete mode 100755 misc/cronjobs/fines-ll.pl delete mode 100755 misc/cronjobs/fines-sanop.pl create mode 100755 misc/cronjobs/fines.pl delete mode 100755 misc/cronjobs/fines2.pl diff --git a/C4/Overdues.pm b/C4/Overdues.pm index e735ff9979..3a74f63624 100644 --- a/C4/Overdues.pm +++ b/C4/Overdues.pm @@ -493,9 +493,12 @@ sub UpdateFine { if ( my $data = $sth->fetchrow_hashref ) { - # we're updating an existing fine. + # we're updating an existing fine. Only modify if we're adding to the charge. + # Note that in the current implementation, you cannot pay against an accruing fine + # (i.e. , of accounttype 'FU'). Doing so will break accrual. if ( $data->{'amount'} != $amount ) { my $diff = $amount - $data->{'amount'}; + $diff = 0 if ( $data->{amount} > $amount); my $out = $data->{'amountoutstanding'} + $diff; my $query = " UPDATE accountlines diff --git a/misc/cronjobs/fines-ll.pl b/misc/cronjobs/fines-ll.pl deleted file mode 100755 index e2d28a6c6d..0000000000 --- a/misc/cronjobs/fines-ll.pl +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/perl - -# This script loops through each overdue item, determines the fine, -# and updates the total amount of fines due by each user. It relies on -# the existence of /tmp/fines, which is created by ??? -# Doesnt really rely on it, it relys on being able to write to /tmp/ -# It creates the fines file -# -# This script is meant to be run nightly out of cron. - -# Copyright 2000-2002 Katipo Communications -# -# 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; -BEGIN { - # find Koha's Perl modules - # test carefully before changing this - use FindBin; - eval { require "$FindBin::Bin/kohalib.pl" }; -} -use C4::Context; -use C4::Circulation; -use C4::Overdues; -use C4::Calendar; -use Date::Manip qw/Date_DaysSince1BC/; -use C4::Biblio; -#use Data::Dumper; -# -my $fldir = "/tmp"; - -my $libname=C4::Context->preference('LibraryName'); -my $dbname= C4::Context->config('database'); - -my $SET_LOST = 0; # automatically charge item price at delay=3 if set. - -my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time); -$mon++; -$year=$year+1900; -my $date=Date_DaysSince1BC($mon,$mday,$year); -my $datestr = $year . sprintf("-%02d-%02d",$mon,$mday); -my $filename= $dbname; -$filename =~ s/\W//; -$filename = $fldir . '/'. $filename . $datestr . ".log"; -open (FILE,">$filename") || die "Can't open LOG"; -print FILE "cardnumber\tcategory\tsurname\tfirstname\temail\tphone\taddress\tcitystate\tbarcode\tdate_due\ttype\titemnumber\tdays_overdue\tfine\n"; - -# FIXME -# it looks like $count is just a counter, would it be -# better to rely on the length of the array @$data and turn the -# for loop below into a foreach loop? -# -my $DEBUG =1; -my $data=Getoverdues(); -# warn "Overdues : = ".scalar(@$data)." => ".Data::Dumper::Dumper($data); -my $overdueItemsCounted=0 if $DEBUG; -my $reference = $year."".$mon; -my $borrowernumber; - -for (my $i=0;$i[$i]->{'date_due'}); - my $date2=Date_DaysSince1BC($dates[1],$dates[2],$dates[0]); - my $datedue=$data->[$i]->{'date_due'}; - my $due="$dates[1]/$dates[2]/$dates[0]"; - my $borrower=BorType($data->[$i]->{'borrowernumber'}); - my $branchcode; - if ( C4::Context->preference('CircControl') eq 'ItemHomeLibrary' ) { - $branchcode = $data->[$i]->{'homebranch'}; - } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) { - $branchcode = $borrower->{'branchcode'}; -} else { - # CircControl must be PickupLibrary. (branchcode comes from issues table here). - $branchcode = $data->[$i]->{'branchcode'}; - } - my $calendar = C4::Calendar->new( branchcode => $branchcode ); - - my @dmy = split( '-', C4::Dates->new()->output('metric') ) ; - my $isHoliday = $calendar->isHoliday( split( '/', C4::Dates->new()->output('metric') ) ); - my $starter; - - if ($date2 <= $date){ - $overdueItemsCounted++ if $DEBUG; - my $difference=$date-$date2; - my $start_date = C4::Dates->new($data->[$i]->{'date_due'},'iso'); - my $end_date = C4::Dates->new($datestr,'iso'); - my ($amount,$type,$printout,$daycounttotal,$daycount)= - CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,undef,undef, $start_date,$end_date); - my ($delays1,$delays2,$delays3)=GetOverdueDelays($borrower->{'categorycode'}); - - # Don't update the fine if today is a holiday. - # This ensures that dropbox mode will remove the correct amount of fine. - if( ! $isHoliday ) { - # FIXME - $type is always null, afaict. - UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due) if( $amount > 0 ) ; - } - if($delays1 and $delays2 and $delays3) { - - my $debarredstatus=CheckBorrowerDebarred($borrower->{'borrowernumber'}); - - #DELAYS 1########################################## - if ($amount > 0 && $daycount >= $delays1 && $daycount < $delays2){ - # FIXME : already in GetIssuingRules ? - my $debarred1=GetOverduerules($borrower->{'categorycode'},1); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred1 eq '1' ) and ($debarredstatus eq '0')); - # is there an open "dossier" for this date & borrower - my $getnotifyid=CheckExistantNotifyid($borrower->{'borrowernumber'},$datedue); - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},1,$datedue); - if ($update eq '0'){ - if ($getnotifyid eq '0'){ - $starter=GetNextIdNotify($reference,$borrower->{'borrowernumber'}); - } else { - $starter=$getnotifyid; - } - } - UpdateAccountLines($starter,1,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - - #DELAYS 2################################# - - if ($daycount >= $delays2 && $daycount < $delays3){ - my $debarred2=GetOverduerules($borrower->{'categorycode'},2); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred2 eq '1' ) and ($debarredstatus eq '0')); - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},2,$datedue); - if ($update eq '0'){ - UpdateAccountLines(undef,2,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - } - ############################################### - - #DELAYS 3################################### - if ($daycount >= $delays3 ){ - my $debarred3=GetOverduerules($borrower->{'categorycode'},3); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred3 eq '1' ) and ($debarredstatus eq '0')); - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},3,$datedue); - if ($update eq '0'){ - UpdateAccountLines(undef,3,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - my $items=GetItems($data->[$i]->{'itemnumber'}); - my $todaydate=$year."-".$mon."-".$mday; - # add item price, the item is considered as lost. - my $description="Item Price"; - my $typeaccount="IP"; - my $level="3"; - my $notifyid=GetNotifyId($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - my $timestamp=$todaydate." ".$hour."\:".$min."\:".$sec; - my $create=CheckAccountLineItemInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$typeaccount,$notifyid); - if ($SET_LOST && ($create eq '0') ){ - CreateItemAccountLine($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$todaydate,$items->{'price'},$description,$typeaccount, - $items->{'price'},$timestamp,$notifyid,$level); - } - } - ############################################### - } - - - if ($borrower->{'category_type'} eq 'C'){ - my $query=qq| SELECT * - FROM borrowers - WHERE borrowernumber=?|; - my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare($query); - $sth->execute($borrower->{'guarantorid'}); - my $tdata=$sth->fetchrow_hashref; - $sth->finish; - $borrower->{'phone'}=$tdata->{'phone'}; - } - print FILE "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'surname'}\t$borrower->{'firstname'}\t$borrower->{'email'}\t$borrower->{'phone'}\t$borrower->{'address'}\t$borrower->{'city'}\t$data->[$i]->{'barcode'}\t$data->[$i]->{'date_due'}\t$type\t$data->[$i]->{'itemnumber'}\t$daycounttotal\t$amount\n"; - } -} - -my $numOverdueItems=scalar(@$data); -if ($DEBUG) { - print </tmp/fines') || die; -# FIXME -# it looks like $count is just a counter, would it be -# better to rely on the length of the array @$data and turn the -# for loop below into a foreach loop? -# -my $DEBUG =1; -my $data=Getoverdues(); -# warn "Overdues : = ".scalar(@$data)." => ".Data::Dumper::Dumper($data); -my $overdueItemsCounted=0 if $DEBUG; -# FIXME - There's got to be a better way to figure out what day -# today is. -my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime(time); -$mon++; -$year=$year+1900; -my $date=Date_DaysSince1BC($mon,$mday,$year); -# print "DATE : ".$date if $DEBUG; -if ($mon < '10' ){ -$mon="0".$mon; -} -if ($mday < '10' ){ -$mday="0".$mday; -} -my $reference = $year."".$mon; -my $borrowernumber; - -for (my $i=0;$i[$i]->{'date_due'}); - my $date2=Date_DaysSince1BC($dates[1],$dates[2],$dates[0]); - my $datedue=$data->[$i]->{'date_due'}; - my $due="$dates[2]/$dates[1]/$dates[0]"; - my $borrower=BorType($data->[$i]->{'borrowernumber'}); - my $starter; - - if ($date2 <= $date){ - $overdueItemsCounted++ if $DEBUG; - my $difference=$date-$date2; - my ($amount,$type,$printout,$daycounttotal,$daycount)= - CalcFine($data->[$i]->{'itemnumber'}, - $borrower->{'categorycode'}, - $difference, - $datedue); - - my ($delays1,$delays2,$delays3)=GetOverdueDelays($borrower->{'categorycode'}); - my $issuingrules=GetIssuingRules($data->[$i]->{'itemnumber'},$borrower->{'categorycode'}); - -# warn "$delays1 and $delays2 and $delays3"; -if($delays1 and $delays2 and $delays3) { - - my $debarredstatus=CheckBorrowerDebarred($borrower->{'borrowernumber'}); - - if (($issuingrules->{'fine'} > 0) || ($issuingrules->{'fine'} ne '' )){ - - #DELAYS 1########################################## -# warn "$amount > 0 && $daycount >= $delays1 && $daycount < $delays2"; - if ($amount > 0 && $daycount >= $delays1 && $daycount < $delays2){ - # FIXME : already in GetIssuingRules ? - my $debarred1=GetOverduerules($borrower->{'categorycode'},1); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred1 eq '1' ) and ($debarredstatus eq '0')); - # save fine - UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due); - # is there an open "dossier" for this date & borrower - my $getnotifyid=CheckExistantNotifyid($borrower->{'borrowernumber'},$datedue); - - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},1,$datedue); - if ($update eq '0'){ - if ($getnotifyid eq '0'){ - $starter=GetNextIdNotify($reference,$borrower->{'borrowernumber'}); - - } - else{ - $starter=$getnotifyid; - } - - } - UpdateAccountLines($starter,1,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - ############################################### - #SANOP specific - if ($daycount>=$delays2) { - - $amount=$issuingrules->{'fine'} * ($delays2); - UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due); - - } - - #DELAYS 2################################# - - if ($daycount >= $delays2 && $daycount < $delays3){ - my $debarred2=GetOverduerules($borrower->{'categorycode'},2); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred2 eq '1' ) and ($debarredstatus eq '0')); - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},2,$datedue); - if ($update eq '0'){ - UpdateAccountLines(undef,2,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - } - ############################################### - - #DELAYS 3################################### - if ($daycount >= $delays3 ){ - my $debarred3=GetOverduerules($borrower->{'categorycode'},3); - (UpdateBorrowerDebarred($borrower->{'borrowernumber'}))if(($debarred3 eq '1' ) and ($debarredstatus eq '0')); - my $update=CheckAccountLineLevelInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},3,$datedue); - if ($update eq '0'){ - UpdateAccountLines(undef,3,$borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - } - my $items=GetItems($data->[$i]->{'itemnumber'}); - my $todaydate=$year."-".$mon."-".$mday; - # add item price, the item is considered as lost. - my $description="Item Price"; - my $typeaccount="IP"; - my $level="3"; - my $notifyid=GetNotifyId($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'}); - my $timestamp=$todaydate." ".$hour."\:".$min."\:".$sec; - my $create=CheckAccountLineItemInfo($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$typeaccount,$notifyid); - if ($create eq '0'){ - - CreateItemAccountLine($borrower->{'borrowernumber'},$data->[$i]->{'itemnumber'},$todaydate,$items->{'price'},$description,$typeaccount, - $items->{'price'},$timestamp,$notifyid,$level); - } - } - ############################################### - } -} - - - -if ($borrower->{'category_type'} eq 'C'){ - my $query=qq| SELECT * - FROM borrowers - WHERE borrowernumber=?|; - my $dbh = C4::Context->dbh; - my $sth=$dbh->prepare($query); - $sth->execute($borrower->{'guarantorid'}); - my $tdata=$sth->fetchrow_hashref; - $sth->finish; - $borrower->{'phone'}=$tdata->{'phone'}; - } - print "$printout\t$borrower->{'cardnumber'}\t$borrower->{'category_type'}\t$borrower->{'firstname'}\t$borrower->{'surname'}\t$data->[$i]->{'date_due'}\t$type\t$difference\t$borrower->{'email'}\t$borrower->{'phone'}\t$borrower->{'address'}\t$borrower->{'city'}\t$amount\n"; - } -} - -my $numOverdueItems=scalar(@$data); -if ($DEBUG) { - print <preference('LibraryName'); +my $dbname= C4::Context->config('database'); + +my $today = C4::Dates->new(); +my $datestr = $today->output('iso'); +my $today_days= Date_to_Days(split(/-/,$today->output('iso'))); +my $filename= $dbname; +$filename =~ s/\W//; +$filename = $fldir . '/'. $filename . $datestr . ".log"; +open (FILE,">$filename") || die "Can't open LOG"; +print FILE "cardnumber\tcategory\tsurname\tfirstname\temail\tphone\taddress\tcitystate\tbarcode\tdate_due\ttype\titemnumber\tdays_overdue\tfine\n"; + + +my $DEBUG =1; + +my $data=Getoverdues(); +my $overdueItemsCounted=0 ; +my $borrowernumber; + +for (my $i=0;$inew($data->[$i]->{'date_due'},'iso'); + my $datedue_days = Date_to_Days(split(/-/,$datedue->output('iso'))); + my $due_str=$datedue->output(); + my $borrower=BorType($data->[$i]->{'borrowernumber'}); + my $branchcode; + if ( C4::Context->preference('CircControl') eq 'ItemHomeLibrary' ) { + $branchcode = $data->[$i]->{'homebranch'}; + } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) { + $branchcode = $borrower->{'branchcode'}; +} else { + # CircControl must be PickupLibrary. (branchcode comes from issues table here). + $branchcode = $data->[$i]->{'branchcode'}; + } + my $calendar = C4::Calendar->new( branchcode => $branchcode ); + + my $isHoliday = $calendar->isHoliday( split( '/', C4::Dates->new()->output('metric') ) ); + + if ($datedue_days <= $today_days){ + $overdueItemsCounted++ if $DEBUG; + my $difference=$today_days - $datedue_days; + my ($amount,$type,$printout,$daycounttotal,$daycount)= + CalcFine($data->[$i], $borrower->{'categorycode'}, $branchcode,undef,undef, $datedue ,$today); + my ($delays1,$delays2,$delays3)=GetOverdueDelays($borrower->{'categorycode'}); + + # Don't update the fine if today is a holiday. + # This ensures that dropbox mode will remove the correct amount of fine. + if( (C4::Context->preference('finesMode') eq 'production') && ! $isHoliday ) { + # FIXME - $type is always null, afaict. + UpdateFine($data->[$i]->{'itemnumber'},$data->[$i]->{'borrowernumber'},$amount,$type,$due_str) if( $amount > 0 ) ; + } + print FILE "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'surname'}\t$borrower->{'firstname'}\t$borrower->{'email'}\t$borrower->{'phone'}\t$borrower->{'address'}\t$borrower->{'city'}\t$data->[$i]->{'barcode'}\t$data->[$i]->{'date_due'}\t$type\t$data->[$i]->{'itemnumber'}\t$daycounttotal\t$amount\n"; + } +} + +my $numOverdueItems=scalar(@$data); +if ($DEBUG) { + print <$filename") or die "Cannot write to $filename"; - -my ($data)=Getoverdues(); -my $overdueItemsCounted=0; - -# FIXME - There's got to be a better way to figure out what day today is. -my ($mday,$mon,$year) = (localtime)[3..5]; # ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) -my $date = Date_DaysSince1BC($mon+1,$mday,$year+1900); -my $today_obj = C4::Dates->new(); -my $today_iso = $today_obj->output('iso'); - -if ($verbose) { - printf "Number of overdues: %7d\nDate_DaysSince1BC : %7d\n", scalar(@$data), $date; - print "today: $today_iso\n"; -} - -# get the maxfine parameter -my $maxFine=C4::Context->preference("MaxFine") || 999999999; - -our $phone_sth = C4::Context->dbh->prepare("Select * from borrowers where borrowernumber=?"); -sub get_guarantor_phone ($) { - $phone_sth->execute(shift); - my $x = $phone_sth->fetchrow_hashref; - return $x->{'phone'}; -} - -our $fine_sth = C4::Context->dbh->prepare(" - INSERT INTO accountlines - (borrowernumber, itemnumber, accountno, date, - amount, description, accounttype, amountoutstanding) - VALUES (?,?,?,now(),?,?,'L',?) - "); -sub insert_fine ($$$$$$) { - $verbose and print "inserting fine: " . join(", ",@_), "\n"; - return $fine_sth->execute(@_); -} - -my $circcontrol = C4::Context->preference('CircControl'); -foreach (@$data){ - my $date_due = $_->{date_due}; - $verbose and print "date_due: $date_due ", ($date_due le $today_iso ? 'fine!' : 'ok'), "\n"; - my @dates=split('-',$date_due); - my $date2=Date_DaysSince1BC($dates[1],$dates[2],$dates[0]); - my $due="$dates[2]/$dates[1]/$dates[0]"; - my $borrowernumber = $_->{borrowernumber}; - my $itemnumber = $_->{itemnumber}; - my $borrower = BorType($borrowernumber); - ($date_due le $today_iso) or next; # it is valid to string compare ISO dates. - $overdueItemsCounted++ if $verbose; - my $branchcode = ($circcontrol eq 'PatronLibrary' ) ? $borrower->{branchcode} : - ($circcontrol eq 'ItemHomeLibrary') ? $_->{homebranch} : - $_->{branchcode} ; # Last option: Pickup Library. - my $difference=$date-$date2; - my (@calc_returns) = CalcFine( - $_, $borrower->{categorycode}, $branchcode,undef,undef, C4::Dates->new($date_due,'iso'), $today_obj - ); - if ($verbose) { - my $dump = Dumper($_); - $dump =~ s/;/,/; - $verbose and print "CalcFine($dump" . - "\t$borrower->{categorycode}, $branchcode,undef,undef,[$date_due],[today]) returns:\n" . Dumper(\@calc_returns), "\n"; - } - my ($amount,$type,$printout) = @calc_returns[0..2]; - # ($amount,$chargename,$daycount,$daycounttotal)=&CalcFine($itemnumber,$categorycode,$branch,$days_overdue,$description, $start_date, $end_date ); - - ($amount > $maxFine) and $amount = $maxFine; - if ($amount > 0) { - UpdateFine($itemnumber,$borrowernumber,$amount,$type,$due); - if ($borrower->{'guarantorid'}) { - $borrower->{'phone'} = get_guarantor_phone($borrower->{'guarantorid'}) || $borrower->{'phone'}; - } - print "$printout\t$borrower->{'cardnumber'}\t$borrower->{'categorycode'}\t$borrower->{'firstname'}\t$borrower->{'surname'}\t", - "$_->{'date_due'}\t$type\t$difference\t", - "$borrower->{'emailaddress'}\t$borrower->{'phone'}\t$borrower->{'streetaddress'}\t$borrower->{'city'}\t$amount\n" if $verbose; - } - if ($difference >= C4::Context->preference("NoReturnSetLost")){ - my $borrower=BorType($borrowernumber); - if ($borrower->{'cardnumber'} ne ''){ - my $cost = ReplacementCost($itemnumber); - my $item = GetBiblioFromItemNumber($itemnumber); - if ($item->{'itemlost'} ne '1' && $item->{'itemlost'} ne '2' ){ - insert_fine( - $borrowernumber, - $itemnumber, - C4::Accounts::getnextacctno($borrowernumber), - $cost, - "Lost item $item->{'title'} $item->{'barcode'} $due", - $cost - ); - ModItem({ itemlost => 2 }, undef, $itemnumber); - } - } - } -} - -if ($verbose) { - my $numOverdueItems=scalar(@$data); - print <