use C4::Branch; # GetBranches
use C4::Log; # logaction
use C4::Koha qw(GetAuthorisedValueByCode);
+use C4::Overdues qw(CalcFine UpdateFine);
use Data::Dumper;
use Koha::DateUtils;
use Koha::Calendar;
BEGIN {
require Exporter;
- $VERSION = 3.02; # for version checking
+ $VERSION = 3.07.00.049; # for version checking
@ISA = qw(Exporter);
# FIXME subs that should probably be elsewhere
my ( $borrower, $barcode, $duedate, $inprocess, $ignore_reserves ) = @_;
my %needsconfirmation; # filled with problems that needs confirmations
my %issuingimpossible; # filled with problems that causes the issue to be IMPOSSIBLE
+ my %alerts; # filled with messages that shouldn't stop issuing, but the librarian should be aware of.
+
my $item = GetItem(GetItemnumberFromBarcode( $barcode ));
my $issue = GetItemIssue($item->{itemnumber});
my $biblioitem = GetBiblioItemData($item->{biblioitemnumber});
}
if ($duedate) {
my $today = $now->clone();
- $today->truncate( to => 'minutes');
+ $today->truncate( to => 'minute');
if (DateTime->compare($duedate,$today) == -1 ) { # duedate cannot be before now
$needsconfirmation{INVALID_DATE} = output_pref($duedate);
}
day => $d,
time_zone => C4::Context->tz,
);
- $expiry_dt->truncate( to => 'days');
- my $today = $now->clone()->truncate(to => 'days');
+ $expiry_dt->truncate( to => 'day');
+ my $today = $now->clone()->truncate(to => 'day');
if (DateTime->compare($today, $expiry_dt) == 1) {
$issuingimpossible{EXPIRED} = 1;
}
{
$issuingimpossible{RESTRICTED} = 1;
}
- if ( $item->{'itemlost'} ) {
- $needsconfirmation{ITEM_LOST} = GetAuthorisedValueByCode( 'LOST', $item->{'itemlost'} );
+ if ( $item->{'itemlost'} && C4::Context->preference("IssueLostItem") ne 'nothing' ) {
+ my $code = GetAuthorisedValueByCode( 'LOST', $item->{'itemlost'} );
+ $needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' );
+ $alerts{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' );
}
if ( C4::Context->preference("IndependantBranches") ) {
my $userenv = C4::Context->userenv;
}
}
}
- return ( \%issuingimpossible, \%needsconfirmation );
+ return ( \%issuingimpossible, \%needsconfirmation, \%alerts );
}
=head2 AddIssue
$datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower );
}
- $datedue->truncate( to => 'minutes');
+ $datedue->truncate( to => 'minute');
$sth->execute(
$borrower->{'borrowernumber'}, # borrowernumber
$item->{'itemnumber'}, # itemnumber
sub AddReturn {
my ( $barcode, $branch, $exemptfine, $dropbox ) = @_;
+
if ($branch and not GetBranchDetail($branch)) {
warn "AddReturn error: branch '$branch' not found. Reverting to " . C4::Context->userenv->{'branch'};
undef $branch;
$branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr;
}
- # if indy branches and returning to different branch, refuse the return
- if ($hbr ne $branch && C4::Context->preference("IndependantBranches")){
+ # if indy branches and returning to different branch, refuse the return unless canreservefromotherbranches is turned on
+ if ($hbr ne $branch && C4::Context->preference("IndependantBranches") && !(C4::Context->preference("canreservefromotherbranches"))){
$messages->{'Wrongbranch'} = {
Wrongbranch => $branch,
Rightbranch => $hbr,
# case of a return of document (deal with issues and holdingbranch)
if ($doreturn) {
+ my $today = DateTime->now( time_zone => C4::Context->tz() );
+ my $datedue = $issue->{date_due};
$borrower or warn "AddReturn without current borrower";
my $circControlBranch;
if ($dropbox) {
# FIXME: check issuedate > returndate, factoring in holidays
#$circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );;
$circControlBranch = _GetCircControlBranch($item,$borrower);
+ my $datedue = $issue->{date_due};
+ $issue->{'overdue'} = DateTime->compare($issue->{'date_due'}, $today ) == -1 ? 1 : 0;
}
if ($borrowernumber) {
+ if($issue->{'overdue'}){
+ my ( $amount, $type, $daycounttotal ) = C4::Overdues::CalcFine( $item, $borrower->{categorycode},$branch, $datedue, $today );
+ $type ||= q{};
+ if ( $amount > 0 && ( C4::Context->preference('finesMode') eq 'production' )) {
+ C4::Overdues::UpdateFine(
+ $issue->{itemnumber},
+ $issue->{borrowernumber},
+ $amount, $type, output_pref($datedue)
+ );
+ }
+ }
MarkIssueReturned($borrowernumber, $item->{'itemnumber'}, $circControlBranch, '', $borrower->{'privacy'});
$messages->{'WasReturned'} = 1; # FIXME is the "= 1" right? This could be the borrower hash.
}
sub MarkIssueReturned {
my ( $borrowernumber, $itemnumber, $dropbox_branch, $returndate, $privacy ) = @_;
+
my $dbh = C4::Context->dbh;
my $query = 'UPDATE issues SET returndate=';
my @bind;
my $circcontrol = C4::Context::preference('CircControl');
my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
my $finedays = $issuingrule->{finedays};
+ my $unit = $issuingrule->{lengthunit};
# exit if no finedays defined
return unless $finedays;
- my $grace = DateTime::Duration->new( days => $issuingrule->{firstremind} );
+ # finedays is in days, so hourly loans must multiply by 24
+ # thus 1 hour late equals 1 day suspension * finedays rate
+ $finedays = $finedays * 24 if ($unit eq 'hours');
+
+ # grace period is measured in the same units as the loan
+ my $grace = DateTime::Duration->new( $unit => $issuingrule->{firstremind} );
if ( ( $deltadays - $grace )->is_positive ) { # you can't compare DateTime::Durations with logical operators
my $new_debar_dt = $dt_today->clone()->add_duration( $deltadays * $finedays );
my $data = $sth->fetchrow_hashref;
return unless $data;
$data->{issuedate} = dt_from_string($data->{issuedate}, 'sql');
- $data->{issuedate}->truncate(to => 'minutes');
+ $data->{issuedate}->truncate(to => 'minute');
$data->{date_due} = dt_from_string($data->{date_due}, 'sql');
- $data->{date_due}->truncate(to => 'minutes');
- my $dt = DateTime->now( time_zone => C4::Context->tz)->truncate( to => 'minutes');
+ $data->{date_due}->truncate(to => 'minute');
+ my $dt = DateTime->now( time_zone => C4::Context->tz)->truncate( to => 'minute');
$data->{'overdue'} = DateTime->compare($data->{'date_due'}, $dt ) == -1 ? 1 : 0;
return $data;
}
my ( $itemnumber, $history ) = @_;
my $today = DateTime->now( time_zome => C4::Context->tz); # get today date
- $today->truncate( to => 'minutes' );
+ $today->truncate( to => 'minute' );
my $sql = "SELECT * FROM issues
JOIN borrowers USING (borrowernumber)
JOIN items USING (itemnumber)
my $results = $sth->fetchall_arrayref({});
foreach (@$results) {
my $date_due = dt_from_string($_->{date_due},'sql');
- $date_due->truncate( to => 'minutes' );
+ $date_due->truncate( to => 'minute' );
$_->{overdue} = (DateTime->compare($date_due, $today) == -1) ? 1 : 0;
}
}
) or return;
- my @transports = @{ $borrower_preferences->{transports} };
+ my @transports = keys %{ $borrower_preferences->{transports} };
# warn "no transports" unless @transports;
for (@transports) {
# warn "transport: $_";
# if a borrower lost the item, add a replacement cost to the their record
if ( my $borrowernumber = $issues->{borrowernumber} ){
+ my $borrower = C4::Members::GetMemberDetails( $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;
+ MarkIssueReturned($borrowernumber,$itemnumber,undef,undef,$borrower->{'privacy'}) if $mark_returned;
}
}