use Koha::Account::Lines;
use Koha::Account::Offsets;
use Koha::Config::SysPrefs;
+use Koha::Charges::Fees;
use Carp;
use List::MoreUtils qw( uniq any );
use Scalar::Util qw( looks_like_number );
|;
my $rule_itemtype = $maxissueqty_rule->itemtype;
- if ($rule_itemtype eq "*") {
+ unless ($rule_itemtype) {
# matching rule has the default item type, so count only
# those existing loans that don't fall under a more
# specific rule
$count_query .= " AND borrowernumber = ? ";
push @bind_params, $borrower->{'borrowernumber'};
my $rule_branch = $maxissueqty_rule->branchcode;
- if ($rule_branch ne "*") {
+ unless ($rule_branch) {
if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
$count_query .= " AND issues.branchcode = ? ";
push @bind_params, $branch;
my ( $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $count_query, {}, @bind_params );
- my $max_checkouts_allowed = $maxissueqty_rule ? $maxissueqty_rule->rule_value : 0;
- my $max_onsite_checkouts_allowed = $maxonsiteissueqty_rule ? $maxonsiteissueqty_rule->rule_value : 0;
+ my $max_checkouts_allowed = $maxissueqty_rule ? $maxissueqty_rule->rule_value : undef;
+ my $max_onsite_checkouts_allowed = $maxonsiteissueqty_rule ? $maxonsiteissueqty_rule->rule_value : undef;
if ( $onsite_checkout and defined $max_onsite_checkouts_allowed ) {
if ( $onsite_checkout_count >= $max_onsite_checkouts_allowed ) {
# Now count total loans against the limit for the branch
my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower);
- if (defined($branch_borrower_circ_rule->{maxissueqty})) {
+ if (defined($branch_borrower_circ_rule->{patron_maxissueqty}) and $branch_borrower_circ_rule->{patron_maxissueqty} ne '') {
my @bind_params = ();
my $branch_count_query = q|
SELECT COUNT(*) AS total, COALESCE(SUM(onsite_checkout), 0) AS onsite_checkouts
push @bind_params, $branch;
}
my ( $checkout_count, $onsite_checkout_count ) = $dbh->selectrow_array( $branch_count_query, {}, @bind_params );
- my $max_checkouts_allowed = $branch_borrower_circ_rule->{maxissueqty};
- my $max_onsite_checkouts_allowed = $branch_borrower_circ_rule->{maxonsiteissueqty};
+ my $max_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxissueqty};
+ my $max_onsite_checkouts_allowed = $branch_borrower_circ_rule->{patron_maxonsiteissueqty};
- if ( $onsite_checkout and defined $max_onsite_checkouts_allowed ) {
+ if ( $onsite_checkout and $max_onsite_checkouts_allowed ne '' ) {
if ( $onsite_checkout_count >= $max_onsite_checkouts_allowed ) {
return {
reason => 'TOO_MANY_ONSITE_CHECKOUTS',
}
}
- if ( not defined( $maxissueqty_rule ) and not defined($branch_borrower_circ_rule->{maxissueqty}) ) {
+ if ( not defined( $maxissueqty_rule ) and not defined($branch_borrower_circ_rule->{patron_maxissueqty}) ) {
return { reason => 'NO_RULE_DEFINED', max_allowed => 0 };
}
my $onsite_checkout = $params->{onsite_checkout} || 0;
my $override_high_holds = $params->{override_high_holds} || 0;
- my $item = Koha::Items->find({barcode => $barcode });
+ my $item_object = Koha::Items->find({barcode => $barcode });
+
# MANDATORY CHECKS - unless item exists, nothing else matters
- unless ( $item ) {
+ unless ( $item_object ) {
$issuingimpossible{UNKNOWN_BARCODE} = 1;
}
return ( \%issuingimpossible, \%needsconfirmation ) if %issuingimpossible;
- my $item_unblessed = $item->unblessed; # Transition...
- my $issue = $item->checkout;
- my $biblio = $item->biblio;
+ my $item_unblessed = $item_object->unblessed; # Transition...
+ my $issue = $item_object->checkout;
+ my $biblio = $item_object->biblio;
+
my $biblioitem = $biblio->biblioitem;
- my $effective_itemtype = $item->effective_itemtype;
+ my $effective_itemtype = $item_object->effective_itemtype;
my $dbh = C4::Context->dbh;
my $patron_unblessed = $patron->unblessed;
+ my $circ_library = Koha::Libraries->find( _GetCircControlBranch($item_unblessed, $patron_unblessed) );
#
# DUE DATE is OK ? -- should already have checked.
#
unless ( $duedate ) {
my $issuedate = $now->clone();
- my $branch = _GetCircControlBranch($item_unblessed, $patron_unblessed);
+ my $branch = $circ_library;
$duedate = CalcDateDue( $issuedate, $effective_itemtype, $branch, $patron_unblessed );
# Offline circ calls AddIssue directly, doesn't run through here
# So issuingimpossible should be ok.
}
+
+ my $fees = Koha::Charges::Fees->new(
+ {
+ patron => $patron,
+ library => $circ_library,
+ item => $item_object,
+ to_date => $duedate,
+ }
+ );
+
if ($duedate) {
my $today = $now->clone();
$today->truncate( to => 'minute');
#
# BORROWER STATUS
#
- if ( $patron->category->category_type eq 'X' && ( $item->barcode )) {
+ if ( $patron->category->category_type eq 'X' && ( $item_object->barcode )) {
# stats only borrower -- add entry to statistics table, and return issuingimpossible{STATS} = 1 .
&UpdateStats({
branch => C4::Context->userenv->{'branch'},
type => 'localuse',
- itemnumber => $item->itemnumber,
+ itemnumber => $item_object->itemnumber,
itemtype => $effective_itemtype,
borrowernumber => $patron->borrowernumber,
- ccode => $item->ccode}
+ ccode => $item_object->ccode}
);
- ModDateLastSeen( $item->itemnumber ); # FIXME Move to Koha::Item
+ ModDateLastSeen( $item_object->itemnumber ); # FIXME Move to Koha::Item
return( { STATS => 1 }, {});
}
} else {
my ($CanBookBeRenewed,$renewerror) = CanBookBeRenewed(
$patron->borrowernumber,
- $item->itemnumber,
+ $item_object->itemnumber,
);
if ( $CanBookBeRenewed == 0 ) { # no more renewals allowed
if ( $renewerror eq 'onsite_checkout' ) {
and $issue
and $issue->onsite_checkout
and $issue->borrowernumber == $patron->borrowernumber ? 1 : 0 );
- my $toomany = TooMany( $patron_unblessed, $item->biblionumber, $item_unblessed, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } );
+ my $toomany = TooMany( $patron_unblessed, $item_object->biblionumber, $item_unblessed, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } );
# if TooMany max_allowed returns 0 the user doesn't have permission to check out this book
if ( $toomany && not exists $needsconfirmation{RENEW_ISSUE} ) {
if ( $toomany->{max_allowed} == 0 ) {
#
# ITEM CHECKING
#
- if ( $item->notforloan )
+ if ( $item_object->notforloan )
{
if(!C4::Context->preference("AllowNotForLoanOverride")){
$issuingimpossible{NOT_FOR_LOAN} = 1;
- $issuingimpossible{item_notforloan} = $item->notforloan;
+ $issuingimpossible{item_notforloan} = $item_object->notforloan;
}else{
$needsconfirmation{NOT_FOR_LOAN_FORCING} = 1;
- $needsconfirmation{item_notforloan} = $item->notforloan;
+ $needsconfirmation{item_notforloan} = $item_object->notforloan;
}
}
else {
}
}
}
- if ( $item->withdrawn && $item->withdrawn > 0 )
+ if ( $item_object->withdrawn && $item_object->withdrawn > 0 )
{
$issuingimpossible{WTHDRAWN} = 1;
}
- if ( $item->restricted
- && $item->restricted == 1 )
+ if ( $item_object->restricted
+ && $item_object->restricted == 1 )
{
$issuingimpossible{RESTRICTED} = 1;
}
- if ( $item->itemlost && C4::Context->preference("IssueLostItem") ne 'nothing' ) {
- my $av = Koha::AuthorisedValues->search({ category => 'LOST', authorised_value => $item->itemlost });
+ if ( $item_object->itemlost && C4::Context->preference("IssueLostItem") ne 'nothing' ) {
+ my $av = Koha::AuthorisedValues->search({ category => 'LOST', authorised_value => $item_object->itemlost });
my $code = $av->count ? $av->next->lib : '';
$needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' );
$alerts{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' );
my $userenv = C4::Context->userenv;
unless ( C4::Context->IsSuperLibrarian() ) {
my $HomeOrHoldingBranch = C4::Context->preference("HomeOrHoldingBranch");
- if ( $item->$HomeOrHoldingBranch ne $userenv->{branch} ){
+ if ( $item_object->$HomeOrHoldingBranch ne $userenv->{branch} ){
$issuingimpossible{ITEMNOTSAMEBRANCH} = 1;
- $issuingimpossible{'itemhomebranch'} = $item->$HomeOrHoldingBranch;
+ $issuingimpossible{'itemhomebranch'} = $item_object->$HomeOrHoldingBranch;
}
$needsconfirmation{BORRNOTSAMEBRANCH} = $patron->branchcode
if ( $patron->branchcode ne $userenv->{branch} );
my $rentalConfirmation = C4::Context->preference("RentalFeesCheckoutConfirmation");
if ( $rentalConfirmation ){
- my ($rentalCharge) = GetIssuingCharges( $item->itemnumber, $patron->borrowernumber );
+ my ($rentalCharge) = GetIssuingCharges( $item_object->itemnumber, $patron->borrowernumber );
+ my $itemtype = Koha::ItemTypes->find( $item_object->itype ); # GetItem sets effective itemtype
+ $rentalCharge += $fees->accumulate_rentalcharge({ from => dt_from_string(), to => $duedate });
if ( $rentalCharge > 0 ){
$needsconfirmation{RENTALCHARGE} = $rentalCharge;
}
unless ( $ignore_reserves ) {
# See if the item is on reserve.
- my ( $restype, $res ) = C4::Reserves::CheckReserves( $item->itemnumber );
+ my ( $restype, $res ) = C4::Reserves::CheckReserves( $item_object->itemnumber );
if ($restype) {
my $resbor = $res->{'borrowernumber'};
if ( $resbor ne $patron->borrowernumber ) {
) {
# Check if borrower has already issued an item from the same biblio
# Only if it's not a subscription
- my $biblionumber = $item->biblionumber;
+ my $biblionumber = $item_object->biblionumber;
require C4::Serials;
my $is_a_subscription = C4::Serials::CountSubscriptionFromBiblionumber($biblionumber);
unless ($is_a_subscription) {
# Stop here if the patron or barcode doesn't exist
if ( $borrower && $barcode && $barcodecheck ) {
# find which item we issue
- my $item = Koha::Items->find({ barcode => $barcode })
+ my $item_object = Koha::Items->find({ barcode => $barcode })
or return; # if we don't get an Item, abort.
- my $item_unblessed = $item->unblessed;
+ my $item_unblessed = $item_object->unblessed;
my $branch = _GetCircControlBranch( $item_unblessed, $borrower );
# get actual issuing if there is one
- my $actualissue = $item->checkout;
+ my $actualissue = $item_object->checkout;
# check if we just renew the issue.
if ( $actualissue and $actualissue->borrowernumber eq $borrower->{'borrowernumber'}
and not $switch_onsite_checkout ) {
$datedue = AddRenewal(
$borrower->{'borrowernumber'},
- $item->itemnumber,
+ $item_object->itemnumber,
$branch,
$datedue,
$issuedate, # here interpreted as the renewal date
);
}
else {
+ unless ($datedue) {
+ my $itype = $item_object->effective_itemtype;
+ $datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower );
+
+ }
+ $datedue->truncate( to => 'minute' );
+
+ my $patron = Koha::Patrons->find( $borrower );
+ my $library = Koha::Libraries->find( $branch );
+ my $fees = Koha::Charges::Fees->new(
+ {
+ patron => $patron,
+ library => $library,
+ item => $item_object,
+ to_date => $datedue,
+ }
+ );
+
# it's NOT a renewal
if ( $actualissue and not $switch_onsite_checkout ) {
# 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
my ( $allowed, $message ) = CanBookBeReturned( $item_unblessed, C4::Context->userenv->{branch} );
return unless $allowed;
- AddReturn( $item->barcode, C4::Context->userenv->{'branch'} );
+ AddReturn( $item_object->barcode, C4::Context->userenv->{'branch'} );
}
- C4::Reserves::MoveReserve( $item->itemnumber, $borrower->{'borrowernumber'}, $cancelreserve );
+ C4::Reserves::MoveReserve( $item_object->itemnumber, $borrower->{'borrowernumber'}, $cancelreserve );
# Starting process for transfer job (checking transfert and validate it if we have one)
- my ($datesent) = GetTransfers( $item->itemnumber );
+ my ($datesent) = GetTransfers( $item_object->itemnumber );
if ($datesent) {
# updating line of branchtranfert to finish it, and changing the to branch value, implement a comment for visibility of this case (maybe for stats ....)
my $sth = $dbh->prepare(
WHERE itemnumber= ? AND datearrived IS NULL"
);
$sth->execute( C4::Context->userenv->{'branch'},
- $item->itemnumber );
+ $item_object->itemnumber );
}
# If automatic renewal wasn't selected while issuing, set the value according to the issuing rule.
unless ($auto_renew) {
my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
{ categorycode => $borrower->{categorycode},
- itemtype => $item->effective_itemtype,
+ itemtype => $item_object->effective_itemtype,
branchcode => $branch
}
);
# Record in the database the fact that the book was issued.
unless ($datedue) {
- my $itype = $item->effective_itemtype;
+ my $itype = $item_object->effective_itemtype;
$datedue = CalcDateDue( $issuedate, $itype, $branch, $borrower );
}
auto_renew => $auto_renew ? 1 : 0,
};
- $issue = Koha::Checkouts->find( { itemnumber => $item->itemnumber } );
+ $issue = Koha::Checkouts->find( { itemnumber => $item_object->itemnumber } );
if ($issue) {
$issue->set($issue_attributes)->store;
}
else {
$issue = Koha::Checkout->new(
{
- itemnumber => $item->itemnumber,
+ itemnumber => $item_object->itemnumber,
%$issue_attributes,
}
)->store;
if ( C4::Context->preference('ReturnToShelvingCart') ) {
# ReturnToShelvingCart is on, anything issued should be taken off the cart.
- CartToShelf( $item->itemnumber );
+ CartToShelf( $item_object->itemnumber );
}
if ( C4::Context->preference('UpdateTotalIssuesOnCirc') ) {
- UpdateTotalIssues( $item->biblionumber, 1 );
+ UpdateTotalIssues( $item_object->biblionumber, 1 );
}
## If item was lost, it has now been found, reverse any list item charges if necessary.
- if ( $item->itemlost ) {
+ if ( $item_object->itemlost ) {
if (
Koha::RefundLostItemFeeRules->should_refund(
{
current_branch => C4::Context->userenv->{branch},
- item_home_branch => $item->homebranch,
- item_holding_branch => $item->holdingbranch,
+ item_home_branch => $item_object->homebranch,
+ item_holding_branch => $item_object->holdingbranch,
}
)
)
{
- _FixAccountForLostAndReturned( $item->itemnumber, undef,
- $item->barcode );
+ _FixAccountForLostAndReturned( $item_object->itemnumber, undef,
+ $item_object->barcode );
}
}
ModItem(
{
- issues => $item->issues + 1,
+ issues => $item_object->issues + 1,
holdingbranch => C4::Context->userenv->{'branch'},
itemlost => 0,
onloan => $datedue->ymd(),
datelastborrowed => DateTime->now( time_zone => C4::Context->tz() )->ymd(),
},
- $item->biblionumber,
- $item->itemnumber,
+ $item_object->biblionumber,
+ $item_object->itemnumber,
{ log_action => 0 }
);
- ModDateLastSeen( $item->itemnumber );
+ ModDateLastSeen( $item_object->itemnumber );
- # If it costs to borrow this book, charge it to the patron's account.
- my ( $charge, $itemtype ) = GetIssuingCharges( $item->itemnumber, $borrower->{'borrowernumber'} );
+ # If it costs to borrow this book, charge it to the patron's account.
+ my ( $charge, $itemtype ) = GetIssuingCharges( $item_object->itemnumber, $borrower->{'borrowernumber'} );
if ( $charge > 0 ) {
- AddIssuingCharge( $issue, $charge );
+ my $description = "Rental";
+ AddIssuingCharge( $issue, $charge, $description );
+ }
+
+ my $itemtype_object = Koha::ItemTypes->find( $item_object->effective_itemtype );
+ if ( $itemtype_object ) {
+ my $accumulate_charge = $fees->accumulate_rentalcharge();
+ if ( $accumulate_charge > 0 ) {
+ AddIssuingCharge( $issue, $accumulate_charge, 'Daily rental' ) if $accumulate_charge > 0;
+ $charge += $accumulate_charge;
+ $item_unblessed->{charge} = $charge;
+ }
}
# Record the fact that this book was issued.
type => ( $onsite_checkout ? 'onsite_checkout' : 'issue' ),
amount => $charge,
other => ( $sipmode ? "SIP-$sipmode" : '' ),
- itemnumber => $item->itemnumber,
- itemtype => $item->effective_itemtype,
- location => $item->location,
+ itemnumber => $item_object->itemnumber,
+ itemtype => $item_object->effective_itemtype,
+ location => $item_object->location,
borrowernumber => $borrower->{'borrowernumber'},
- ccode => $item->ccode,
+ ccode => $item_object->ccode,
}
);
my %conditions = (
branchcode => $branch,
categorycode => $borrower->{categorycode},
- item_type => $item->effective_itemtype,
+ item_type => $item_object->effective_itemtype,
notification => 'CHECKOUT',
);
if ( $circulation_alert->is_enabled_for( \%conditions ) ) {
SendCirculationAlert(
{
type => 'CHECKOUT',
- item => $item->unblessed,
+ item => $item_object->unblessed,
borrower => $borrower,
branch => $branch,
}
logaction(
"CIRCULATION", "ISSUE",
$borrower->{'borrowernumber'},
- $item->itemnumber,
+ $item_object->itemnumber,
) if C4::Context->preference("IssueLog");
}
}
branch and patron category, regardless of item type.
The return value is a hashref containing the following key:
-maxissueqty - maximum number of loans that a
+patron_maxissueqty - maximum number of loans that a
patron of the given category can have at the given
branch. If the value is undef, no limit.
-maxonsiteissueqty - maximum of on-site checkouts that a
+patron_maxonsiteissueqty - maximum of on-site checkouts that a
patron of the given category can have at the given
branch. If the value is undef, no limit.
If no rule has been found in the database, it will default to
the buillt in rule:
-maxissueqty - undef
-maxonsiteissueqty - undef
+patron_maxissueqty - undef
+patron_maxonsiteissueqty - undef
C<$branchcode> and C<$categorycode> should contain the
literal branch code and patron category code, respectively - no
sub GetBranchBorrowerCircRule {
my ( $branchcode, $categorycode ) = @_;
- # Set search prededences
- my @params = (
- {
- branchcode => $branchcode,
- categorycode => $categorycode,
- itemtype => undef,
- },
- {
- branchcode => $branchcode,
- categorycode => undef,
- itemtype => undef,
- },
- {
- branchcode => undef,
- categorycode => $categorycode,
- itemtype => undef,
- },
- {
- branchcode => undef,
- categorycode => undef,
- itemtype => undef,
- },
- );
-
# Initialize default values
my $rules = {
- maxissueqty => undef,
- maxonsiteissueqty => undef,
+ patron_maxissueqty => undef,
+ patron_maxonsiteissueqty => undef,
};
# Search for rules!
- foreach my $rule_name (qw( maxissueqty maxonsiteissueqty )) {
- foreach my $params (@params) {
- my $rule = Koha::CirculationRules->search(
- {
- rule_name => $rule_name,
- %$params,
- }
- )->next();
-
- if ( $rule ) {
- $rules->{$rule_name} = $rule->rule_value;
- last;
+ foreach my $rule_name (qw( patron_maxissueqty patron_maxonsiteissueqty )) {
+ my $rule = Koha::CirculationRules->get_effective_rule(
+ {
+ categorycode => $categorycode,
+ itemtype => undef,
+ branchcode => $branchcode,
+ rule_name => $rule_name,
}
- }
+ );
+
+ $rules->{$rule_name} = $rule->rule_value if defined $rule;
}
return $rules;
=head2 AddReturn
($doreturn, $messages, $iteminformation, $borrower) =
- &AddReturn( $barcode, $branch [,$exemptfine] [,$dropbox] [,$returndate] );
+ &AddReturn( $barcode, $branch [,$exemptfine] [,$returndate] );
Returns a book.
=item C<$exemptfine> indicates that overdue charges for the item will be
removed. Optional.
-=item C<$dropbox> indicates that the check-in date is assumed to be
-yesterday, or the last non-holiday as defined in C4::Calendar . If
-overdue charges are applied and C<$dropbox> is true, the last charge
-will be removed. This assumes that the fines accrual script has run
-for _today_. Optional.
-
=item C<$return_date> allows the default return date to be overridden
by the given return date. Optional.
=cut
sub AddReturn {
- my ( $barcode, $branch, $exemptfine, $dropbox, $return_date, $dropboxdate ) = @_;
+ my ( $barcode, $branch, $exemptfine, $return_date ) = @_;
if ($branch and not Koha::Libraries->find($branch)) {
warn "AddReturn error: branch '$branch' not found. Reverting to " . C4::Context->userenv->{'branch'};
undef $branch;
}
$branch = C4::Context->userenv->{'branch'} unless $branch; # we trust userenv to be a safe fallback/default
+ $return_date //= dt_from_string();
my $messages;
my $patron;
my $doreturn = 1;
}
# case of a return of document (deal with issues and holdingbranch)
- my $today = DateTime->now( time_zone => C4::Context->tz() );
-
if ($doreturn) {
my $is_overdue;
die "The item is not issed and cannot be returned" unless $issue; # Just in case...
$patron or warn "AddReturn without current borrower";
- if ($dropbox) {
- $is_overdue = $issue->is_overdue( $dropboxdate );
- } else {
- $is_overdue = $issue->is_overdue;
- }
+ $is_overdue = $issue->is_overdue( $return_date );
if ($patron) {
eval {
- if ( $dropbox ) {
- MarkIssueReturned( $borrowernumber, $item->itemnumber,
- $dropboxdate, $patron->privacy );
- }
- else {
- MarkIssueReturned( $borrowernumber, $item->itemnumber,
- $return_date, $patron->privacy );
- }
+ MarkIssueReturned( $borrowernumber, $item->itemnumber, $return_date, $patron->privacy );
};
unless ( $@ ) {
- if ( ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) || $return_date ) {
+ if ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) {
_CalculateAndUpdateFine( { issue => $issue, item => $item_unblessed, borrower => $patron_unblessed, return_date => $return_date } );
}
} else {
# fix up the overdues in accounts...
if ($borrowernumber) {
- my $fix = _FixOverduesOnReturn($borrowernumber, $item->itemnumber, $exemptfine, $dropbox);
+ my $fix = _FixOverduesOnReturn( $borrowernumber, $item->itemnumber, $exemptfine );
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->itemnumber...) failed!"; # zero is OK, check defined
if ( $issue and $issue->is_overdue ) {
# fix fine days
- $today = dt_from_string($return_date) if $return_date;
- $today = $dropboxdate if $dropbox;
- my ($debardate,$reminder) = _debar_user_on_return( $patron_unblessed, $item_unblessed, dt_from_string($issue->date_due), $today );
+ my ($debardate,$reminder) = _debar_user_on_return( $patron_unblessed, $item_unblessed, dt_from_string($issue->date_due), $return_date );
if ($reminder){
$messages->{'PrevDebarred'} = $debardate;
} else {
} else {
my $borrower_debar_dt = dt_from_string( $patron->debarred );
$borrower_debar_dt->truncate(to => 'day');
- my $today_dt = $today->clone()->truncate(to => 'day');
+ my $today_dt = $return_date->clone()->truncate(to => 'day');
if ( DateTime->compare( $borrower_debar_dt, $today_dt ) != -1 ) {
$messages->{'PrevDebarred'} = $patron->debarred;
}
=head2 _debar_user_on_return
- _debar_user_on_return($borrower, $item, $datedue, today);
+ _debar_user_on_return($borrower, $item, $datedue, $returndate);
C<$borrower> borrower hashref
C<$datedue> date due DateTime object
-C<$return_date> DateTime object representing the return time
+C<$returndate> DateTime object representing the return time
Internal function, called only by AddReturn that calculates and updates
the user fine days, and debars them if necessary.
my ( $borrower, $item, $dt_due, $return_date ) = @_;
my $branchcode = _GetCircControlBranch( $item, $borrower );
+ $return_date //= dt_from_string();
my $circcontrol = C4::Context->preference('CircControl');
my $issuing_rule = Koha::IssuingRules->get_effective_issuing_rule(
=head2 _FixOverduesOnReturn
- &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode);
+ &_FixOverduesOnReturn($borrowernumber, $itemnumber, $exemptfine);
-C<$brn> borrowernumber
+C<$borrowernumber> borrowernumber
-C<$itm> itemnumber
+C<$itemnumber> itemnumber
C<$exemptfine> BOOL -- remove overdue charge associated with this issue.
-C<$dropboxmode> BOOL -- remove lastincrement on overdue charge associated with this issue.
Internal function
=cut
sub _FixOverduesOnReturn {
- my ($borrowernumber, $item, $exemptfine, $dropbox ) = @_;
+ my ( $borrowernumber, $item, $exemptfine ) = @_;
unless( $borrowernumber ) {
warn "_FixOverduesOnReturn() not supplied valid borrowernumber";
return;
if (C4::Context->preference("FinesLog")) {
&logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
}
- } elsif ($dropbox && $accountline->lastincrement) {
- my $outstanding = $accountline->amountoutstanding - $accountline->lastincrement;
- my $amt = $accountline->amount - $accountline->lastincrement;
-
- Koha::Account::Offset->new(
- {
- debit_id => $accountline->id,
- type => 'Dropbox',
- amount => $accountline->lastincrement * -1,
- }
- )->store();
-
- if ( C4::Context->preference("FinesLog") ) {
- &logaction( "FINES", 'MODIFY', $borrowernumber,
- "Dropbox adjustment $amt, item $item" );
- }
-
- $accountline->accounttype('F');
-
- if ( $outstanding >= 0 && $amt >= 0 ) {
- $accountline->amount($amt);
- $accountline->amountoutstanding($outstanding);
- }
-
} else {
$accountline->accounttype('F');
}
my $datedue = shift;
my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz);
- my $item = Koha::Items->find($itemnumber) or return;
- my $biblio = $item->biblio;
- my $issue = $item->checkout;
- my $item_unblessed = $item->unblessed;
+ my $item_object = Koha::Items->find($itemnumber) or return;
+ my $biblio = $item_object->biblio;
+ my $issue = $item_object->checkout;
+ my $item_unblessed = $item_object->unblessed;
my $dbh = C4::Context->dbh;
my $patron = Koha::Patrons->find( $borrowernumber ) or return; # FIXME Should do more than just return
my $patron_unblessed = $patron->unblessed;
+ my $circ_library = Koha::Libraries->find( _GetCircControlBranch($item_unblessed, $patron_unblessed) );
+
if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) {
_CalculateAndUpdateFine( { issue => $issue, item => $item_unblessed, borrower => $patron_unblessed } );
}
# If the due date wasn't specified, calculate it by adding the
# book's loan length to today's date or the current due date
# based on the value of the RenewalPeriodBase syspref.
+ my $itemtype = $item_object->effective_itemtype;
unless ($datedue) {
- my $itemtype = $item->effective_itemtype;
$datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
dt_from_string( $issue->date_due, 'sql' ) :
DateTime->now( time_zone => C4::Context->tz());
- $datedue = CalcDateDue($datedue, $itemtype, _GetCircControlBranch($item_unblessed, $patron_unblessed), $patron_unblessed, 'is a renewal');
+ $datedue = CalcDateDue($datedue, $itemtype, $circ_library, $patron_unblessed, 'is a renewal');
}
+ my $fees = Koha::Charges::Fees->new(
+ {
+ patron => $patron,
+ library => $circ_library,
+ item => $item_object,
+ from_date => dt_from_string( $issue->date_due, 'sql' ),
+ to_date => dt_from_string($datedue),
+ }
+ );
+
# Update the issues record to have the new due date, and a new count
# of how many times it has been renewed.
my $renews = $issue->renewals + 1;
$sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
# Update the renewal count on the item, and tell zebra to reindex
- $renews = $item->renewals + 1;
- ModItem( { renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $item->biblionumber, $itemnumber, { log_action => 0 } );
+ $renews = $item_object->renewals + 1;
+ ModItem( { renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $item_object->biblionumber, $itemnumber, { log_action => 0 } );
- # Charge a new rental fee, if applicable?
+ # Charge a new rental fee, if applicable
my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
if ( $charge > 0 ) {
- my $accountno = C4::Accounts::getnextacctno( $borrowernumber );
- my $manager_id = 0;
- $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
- my $branchcode = C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
- Koha::Account::Line->new(
- {
- date => dt_from_string(),
- borrowernumber => $borrowernumber,
- accountno => $accountno,
- amount => $charge,
- manager_id => $manager_id,
- accounttype => 'Rent',
- amountoutstanding => $charge,
- itemnumber => $itemnumber,
- branchcode => $branchcode,
- description => 'Renewal of Rental Item '
- . $biblio->title
- . " " . $item->barcode,
- }
- )->store();
+ my $description = "Renewal of Rental Item " . $biblio->title . " " .$item_object->barcode;
+ AddIssuingCharge($issue, $charge, $description);
+ }
+
+ # Charge a new accumulate rental fee, if applicable
+ my $itemtype_object = Koha::ItemTypes->find( $itemtype );
+ if ( $itemtype_object ) {
+ my $accumulate_charge = $fees->accumulate_rentalcharge();
+ if ( $accumulate_charge > 0 ) {
+ my $type_desc = "Renewal of Daily Rental Item " . $biblio->title . " $item_unblessed->{'barcode'}";
+ AddIssuingCharge( $issue, $accumulate_charge, $type_desc )
+ }
+ $charge += $accumulate_charge;
}
# Send a renewal slip according to checkout alert preferencei
my %conditions = (
branchcode => $branch,
categorycode => $patron->categorycode,
- item_type => $item->effective_itemtype,
+ item_type => $itemtype,
notification => 'CHECKOUT',
);
if ( $circulation_alert->is_enabled_for( \%conditions ) ) {
type => 'renew',
amount => $charge,
itemnumber => $itemnumber,
- itemtype => $item->effective_itemtype,
- location => $item->location,
+ itemtype => $itemtype,
+ location => $item_object->location,
borrowernumber => $borrowernumber,
- ccode => $item->ccode,
+ ccode => $item_object->ccode,
}
);
=head2 AddIssuingCharge
- &AddIssuingCharge( $checkout, $charge )
+ &AddIssuingCharge( $checkout, $charge, [$description] )
=cut
sub AddIssuingCharge {
- my ( $checkout, $charge ) = @_;
+ my ( $checkout, $charge, $description ) = @_;
# FIXME What if checkout does not exist?
my $accountline = $account->add_debit(
{
amount => $charge,
- description => 'Rental',
+ description => $description,
note => undef,
user_id => C4::Context->userenv ? C4::Context->userenv->{'number'} : 0,
library_id => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
: ( $control eq 'PatronLibrary' ) ? $borrower->{branchcode}
: $issue->branchcode;
- my $date_returned = $return_date ? dt_from_string($return_date) : dt_from_string();
+ my $date_returned = $return_date ? $return_date : dt_from_string();
my ( $amount, $unitcounttotal, $unitcount ) =
C4::Overdues::CalcFine( $item, $borrower->{categorycode}, $control_branchcode, $datedue, $date_returned );