use strict;
#use warnings; FIXME - Bug 2505
+use DateTime;
use C4::Context;
use C4::Stats;
use C4::Reserves;
use C4::Items;
use C4::Members;
use C4::Dates;
-use C4::Calendar;
+use C4::Dates qw(format_date);
use C4::Accounts;
use C4::ItemCirculationAlertPreference;
-use C4::Dates qw(format_date);
use C4::Message;
use C4::Debug;
-use Date::Calc qw(
- Today
- Today_and_Now
- Add_Delta_YM
- Add_Delta_DHMS
- Date_to_Days
- Day_of_Week
- Add_Delta_Days
- check_date
- Delta_Days
-);
-use POSIX qw(strftime);
use C4::Branch; # GetBranches
use C4::Log; # logaction
#
my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item );
# if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book
- if ($max_loans_allowed eq 0) {
+ if (defined $max_loans_allowed && $max_loans_allowed == 0) {
$needsconfirmation{PATRON_CANT} = 1;
} else {
if($max_loans_allowed){
# check if we just renew the issue.
#
if ($actualissue->{borrowernumber} eq $borrower->{'borrowernumber'}) {
- $datedue = AddRenewal(
- $borrower->{'borrowernumber'},
- $item->{'itemnumber'},
- $branch,
- $datedue,
- $issuedate, # here interpreted as the renewal date
+ $datedue = AddRenewal(
+ $borrower->{'borrowernumber'},
+ $item->{'itemnumber'},
+ $branch,
+ $datedue,
+ $issuedate, # here interpreted as the renewal date
);
}
else {
}
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'});
if ($datesent) {
ModItem({ issues => $item->{'issues'},
holdingbranch => C4::Context->userenv->{'branch'},
itemlost => 0,
- datelastborrowed => C4::Dates->new()->output('iso'),
+ datelastborrowed => DateTime->now(time_zone => C4::Context->tz())->ymd(),
onloan => $datedue->ymd(),
}, $item->{'biblionumber'}, $item->{'itemnumber'});
ModDateLastSeen( $item->{'itemnumber'} );
Retrieves circulation rule attributes that apply to the given
branch and item type, regardless of patron category.
-The return value is a hashref containing the following key:
+The return value is a hashref containing the following keys:
holdallowed => Hold policy for this branch and itemtype. Possible values:
0: No holds allowed.
1: Holds allowed only by patrons that have the same homebranch as the item.
2: Holds allowed from any patron.
+returnbranch => branch to which to return item. Possible values:
+ noreturn: do not return, let item remain where checked in (floating collections)
+ homebranch: return to item's home branch
+
This searches branchitemrules in the following order:
* Same branchcode and itemtype
* branchcode '*', same itemtype
* branchcode and itemtype '*'
-Neither C<$branchcode> nor C<$categorycode> should be '*'.
+Neither C<$branchcode> nor C<$itemtype> should be '*'.
=cut
my $result = {};
my @attempts = (
- ['SELECT holdallowed
+ ['SELECT holdallowed, returnbranch
FROM branch_item_rules
WHERE branchcode = ?
AND itemtype = ?', $branchcode, $itemtype],
- ['SELECT holdallowed
+ ['SELECT holdallowed, returnbranch
FROM default_branch_circ_rules
WHERE branchcode = ?', $branchcode],
- ['SELECT holdallowed
+ ['SELECT holdallowed, returnbranch
FROM default_branch_item_rules
WHERE itemtype = ?', $itemtype],
- ['SELECT holdallowed
+ ['SELECT holdallowed, returnbranch
FROM default_circ_rules'],
);
foreach my $attempt (@attempts) {
my ($query, @bind_params) = @{$attempt};
+ my $search_result = $dbh->selectrow_hashref ( $query , {}, @bind_params );
# Since branch/category and branch/itemtype use the same per-branch
# defaults tables, we have to check that the key we want is set, not
# just that a row was returned
- return $result if ( defined( $result->{'holdallowed'} = $dbh->selectrow_array( $query, {}, @bind_params ) ) );
+ $result->{'holdallowed'} = $search_result->{'holdallowed'} unless ( defined $result->{'holdallowed'} );
+ $result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} );
}
# built-in default circulation rule
- return {
- holdallowed => 2,
- };
+ $result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} );
+ $result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} );
+
+ return $result;
}
=head2 AddReturn
my $item = GetItem($itemnumber) or die "GetItem($itemnumber) failed";
# full item data, but no borrowernumber or checkout info (no issue)
# we know GetItem should work because GetItemnumberFromBarcode worked
- my $hbr = C4::Context->preference("HomeOrHoldingBranchReturn") || "homebranch";
- $hbr = $item->{$hbr} || '';
- # item must be from items table -- issues table has branchcode and issuingbranch, not homebranch nor holdingbranch
+ my $hbr = GetBranchItemRule($item->{'homebranch'}, $item->{'itype'})->{'returnbranch'} || "homebranch";
+ # get the proper branch to which to return the item
+ $hbr = $item->{$hbr} || $branch ;
+ # if $hbr was "noreturn" or any other non-item table value, then it should 'float' (i.e. stay at this branch)
my $borrowernumber = $borrower->{'borrowernumber'} || undef; # we don't know if we had a borrower or not
my $query = 'UPDATE issues SET returndate=';
my @bind;
if ($dropbox_branch) {
- my $calendar = Koha->new( branchcode => $dropbox_branch );
+ my $calendar = Koha::Calendar->new( branchcode => $dropbox_branch );
my $dropboxdate = $calendar->addDate( DateTime->now( time_zone => C4::Context->tz), -1 );
$query .= ' ? ';
- push @bind, $dropboxdate->strftimei('%Y-%m-%d %H:%M');
+ push @bind, $dropboxdate->strftime('%Y-%m-%d %H:%M');
} elsif ($returndate) {
$query .= ' ? ';
push @bind, $returndate;
sub _FixFineDaysOnReturn {
my ( $borrower, $item, $datedue ) = @_;
-
- if ($datedue) {
- $datedue = C4::Dates->new( $datedue, "iso" );
- } else {
- return;
- }
+ return unless ($datedue);
+
+ my $dt_due = dt_from_string( $datedue );
+ my $dt_today = DateTime->now( time_zone => C4::Context->tz() );
my $branchcode = _GetCircControlBranch( $item, $borrower );
- my $calendar = C4::Calendar->new( branchcode => $branchcode );
- my $today = C4::Dates->new();
+ my $calendar = Koha::Calendar->new( branchcode => $branchcode );
- my $deltadays = $calendar->daysBetween( $datedue, C4::Dates->new() );
+ # $deltadays is a DateTime::Duration object
+ my $deltadays = $calendar->days_between( $dt_due, $dt_today );
my $circcontrol = C4::Context::preference('CircControl');
my $issuingrule = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
# 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;
+ my $grace = DateTime::Duration->new( days => $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 $borrower_debar_dt = dt_from_string( $borrower->{debarred} );
+ # check to see if the current debar date is a valid date
+ if ( $borrower->{debarred} && $borrower_debar_dt ) {
+ # if so, is it before the new date? update only if true
+ if ( DateTime->compare( $borrower_debar_dt, $new_debar_dt ) == -1 ) {
+ C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+ return $new_debar_dt->ymd();
}
+ # if the borrower's debar date is not set or valid, debar them
} else {
- C4::Members::DebarMember( $borrower->{borrowernumber}, $isonewdate );
- return $isonewdate;
+ C4::Members::DebarMember( $borrower->{borrowernumber}, $new_debar_dt->ymd() );
+ return $new_debar_dt->ymd();
}
}
}
sub GetItemIssues {
my ( $itemnumber, $history ) = @_;
- my $today = C4::Dates->today('iso'); # get today date
+ my $today = DateTime->now( time_zome => C4::Context->tz); # get today date
+ $today->truncate( to => 'minutes' );
my $sql = "SELECT * FROM issues
JOIN borrowers USING (borrowernumber)
JOIN items USING (itemnumber)
}
my $results = $sth->fetchall_arrayref({});
foreach (@$results) {
- $_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0;
+ my $date_due = dt_from_string($_->{date_due},'sql');
+ $date_due->truncate( to => 'minutes' );
+
+ $_->{overdue} = (DateTime->compare($date_due, $today) == -1) ? 1 : 0;
}
return $results;
}
my $itemnumber = shift or return undef;
my $branch = shift;
my $datedue = shift;
- my $lastreneweddate = shift || C4::Dates->new()->output('iso');
+ my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz)->ymd();
my $item = GetItem($itemnumber) or return undef;
my $biblio = GetBiblioFromItemNumber($itemnumber) or return undef;
}
my $calendar = Koha::Calendar->new( branchcode => $branch );
$datedue = $calendar->addDate( $startdate, $dur, $loanlength->{lengthunit} );
+ if ($loanlength->{lengthunit} eq 'days') {
+ $datedue->set_hour(23);
+ $datedue->set_minute(59);
+ }
}
}
return $datedue;
}
-=head2 CheckValidDatedue
-
- $newdatedue = CheckValidDatedue($date_due,$itemnumber,$branchcode);
-
-This function does not account for holiday exceptions nor does it handle the 'useDaysMode' syspref .
-To be replaced by CalcDateDue() once C4::Calendar use is tested.
-
-this function validates the loan length against the holidays calendar, and adjusts the due date as per the 'useDaysMode' syspref.
-C<$date_due> = returndate calculate with no day check
-C<$itemnumber> = itemnumber
-C<$branchcode> = location of issue (affected by 'CircControl' syspref)
-C<$loanlength> = loan length prior to adjustment
-
-=cut
-
-sub CheckValidDatedue {
-my ($date_due,$itemnumber,$branchcode)=@_;
-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);
- ($dow=0) if ($dow>6);
- my $result=CheckRepeatableHolidays($itemnumber,$dow,$branchcode);
- my $countspecial=CheckSpecialHolidays($years,$month,$day,$itemnumber,$branchcode);
- my $countspecialrepeatable=CheckRepeatableSpecialHolidays($month,$day,$itemnumber,$branchcode);
- if (($result ne '0') or ($countspecial ne '0') or ($countspecialrepeatable ne '0') ){
- $i=0;
- (($years,$month,$day) = Add_Delta_Days($years,$month,$day, 1))if ($i ne '1');
- }
- }
- my $newdatedue=C4::Dates->new(sprintf("%04d-%02d-%02d",$years,$month,$day),'iso');
-return $newdatedue;
-}
-
=head2 CheckRepeatableHolidays