use Koha::Libraries;
use Koha::Account::Lines;
use Koha::Holds;
-use Koha::RefundLostItemFeeRule;
use Koha::RefundLostItemFeeRules;
use Koha::Account::Lines;
use Koha::Account::Offsets;
use Koha::Config::SysPrefs;
use Koha::Charges::Fees;
+use Koha::Util::SystemPreferences;
use Carp;
use List::MoreUtils qw( uniq any );
use Scalar::Util qw( looks_like_number );
unless ( $item ) {
$messages->{'BadBarcode'} = $barcode;
$dotransfer = 0;
+ return ( $dotransfer, $messages );
}
my $itemnumber = $item->itemnumber;
sub TooMany {
my $borrower = shift;
- my $biblionumber = shift;
- my $item = shift;
+ my $item_object = shift;
my $params = shift;
my $onsite_checkout = $params->{onsite_checkout} || 0;
my $switch_onsite_checkout = $params->{switch_onsite_checkout} || 0;
my $dbh = C4::Context->dbh;
my $branch;
# Get which branchcode we need
- $branch = _GetCircControlBranch($item,$borrower);
- my $type = (C4::Context->preference('item-level_itypes'))
- ? $item->{'itype'} # item-level
- : $item->{'itemtype'}; # biblio-level
-
+ $branch = _GetCircControlBranch($item_object->unblessed,$borrower);
+ my $type = $item_object->effective_itemtype;
+
# given branch, patron category, and item type, determine
# applicable issuing rule
my $maxissueqty_rule = Koha::CirculationRules->get_effective_rule(
# if a rule is found and has a loan limit set, count
# how many loans the patron already has that meet that
# rule
- if (defined($maxissueqty_rule) and defined($maxissueqty_rule->rule_value)) {
+ if (defined($maxissueqty_rule) and $maxissueqty_rule->rule_value ne '') {
my @bind_params;
my $count_query = q|
SELECT COUNT(*) AS total, COALESCE(SUM(onsite_checkout), 0) AS onsite_checkouts
$count_query .= " AND borrowernumber = ? ";
push @bind_params, $borrower->{'borrowernumber'};
my $rule_branch = $maxissueqty_rule->branchcode;
- unless ($rule_branch) {
+ if ($rule_branch) {
if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
$count_query .= " AND issues.branchcode = ? ";
- push @bind_params, $branch;
+ push @bind_params, $rule_branch;
} elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
; # if branch is the patron's home branch, then count all loans by patron
} else {
$count_query .= " AND items.homebranch = ? ";
- push @bind_params, $branch;
+ push @bind_params, $rule_branch;
}
}
my $no_issues_charge_guarantees = C4::Context->preference("NoIssuesChargeGuarantees");
$no_issues_charge_guarantees = undef unless looks_like_number( $no_issues_charge_guarantees );
if ( defined $no_issues_charge_guarantees ) {
- my @guarantees = $patron->guarantees();
+ my @guarantees = map { $_->guarantee } $patron->guarantee_relationships();
my $guarantees_non_issues_charges;
foreach my $g ( @guarantees ) {
$guarantees_non_issues_charges += $g->account->non_issues_charges;
$issuingimpossible{RETURN_IMPOSSIBLE} = 1;
$issuingimpossible{branch_to_return} = $message;
} else {
+ if ( C4::Context->preference('AutoReturnCheckedOutItems') ) {
+ $alerts{RETURNED_FROM_ANOTHER} = { patron => $patron };
+ } else {
$needsconfirmation{ISSUED_TO_ANOTHER} = 1;
$needsconfirmation{issued_firstname} = $patron->firstname;
$needsconfirmation{issued_surname} = $patron->surname;
$needsconfirmation{issued_cardnumber} = $patron->cardnumber;
$needsconfirmation{issued_borrowernumber} = $patron->borrowernumber;
+ }
}
}
and $issue
and $issue->onsite_checkout
and $issue->borrowernumber == $patron->borrowernumber ? 1 : 0 );
- my $toomany = TooMany( $patron_unblessed, $item_object->biblionumber, $item_unblessed, { onsite_checkout => $onsite_checkout, switch_onsite_checkout => $switch_onsite_checkout, } );
+ my $toomany = TooMany( $patron_unblessed, $item_object, { 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 ) {
# dynamic means X more than the number of holdable items on the record
# let's get the items
- my @items = $holds->next()->biblio()->items();
+ my @items = $holds->next()->biblio()->items()->as_list;
# Remove any items with status defined to be ignored even if the would not make item unholdable
foreach my $status (@decreaseLoanHighHoldsIgnoreStatuses) {
}
)->store;
}
-
- if ( C4::Context->preference('ReturnToShelvingCart') ) {
- # ReturnToShelvingCart is on, anything issued should be taken off the cart.
+ if ( $item_object->location eq 'CART' && $item_object->permanent_location ne 'CART' ) {
+ ## Item was moved to cart via UpdateItemLocationOnCheckin, anything issued should be taken off the cart.
CartToShelf( $item_object->itemnumber );
}
# 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 ) {
- my $description = "Rental";
- AddIssuingCharge( $issue, $charge, $description );
+ AddIssuingCharge( $issue, $charge, 'rent' );
}
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;
+ AddIssuingCharge( $issue, $accumulate_charge, 'rent_daily' ) if $accumulate_charge > 0;
$charge += $accumulate_charge;
$item_unblessed->{charge} = $charge;
}
sub GetBranchItemRule {
my ( $branchcode, $itemtype ) = @_;
- my $dbh = C4::Context->dbh();
- my $result = {};
-
- my @attempts = (
- ['SELECT holdallowed, returnbranch, hold_fulfillment_policy
- FROM branch_item_rules
- WHERE branchcode = ?
- AND itemtype = ?', $branchcode, $itemtype],
- ['SELECT holdallowed, returnbranch, hold_fulfillment_policy
- FROM default_branch_circ_rules
- WHERE branchcode = ?', $branchcode],
- ['SELECT holdallowed, returnbranch, hold_fulfillment_policy
- FROM default_branch_item_rules
- WHERE itemtype = ?', $itemtype],
- ['SELECT holdallowed, returnbranch, hold_fulfillment_policy
- FROM default_circ_rules'],
+
+ # Search for rules!
+ my $holdallowed_rule = Koha::CirculationRules->get_effective_rule(
+ {
+ branchcode => $branchcode,
+ itemtype => $itemtype,
+ rule_name => 'holdallowed',
+ }
+ );
+ my $hold_fulfillment_policy_rule = Koha::CirculationRules->get_effective_rule(
+ {
+ branchcode => $branchcode,
+ itemtype => $itemtype,
+ rule_name => 'hold_fulfillment_policy',
+ }
+ );
+ my $returnbranch_rule = Koha::CirculationRules->get_effective_rule(
+ {
+ branchcode => $branchcode,
+ itemtype => $itemtype,
+ rule_name => 'returnbranch',
+ }
);
- foreach my $attempt (@attempts) {
- my ($query, @bind_params) = @{$attempt};
- my $search_result = $dbh->selectrow_hashref ( $query , {}, @bind_params )
- or next;
-
- # 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
- $result->{'holdallowed'} = $search_result->{'holdallowed'} unless ( defined $result->{'holdallowed'} );
- $result->{'hold_fulfillment_policy'} = $search_result->{'hold_fulfillment_policy'} unless ( defined $result->{'hold_fulfillment_policy'} );
- $result->{'returnbranch'} = $search_result->{'returnbranch'} unless ( defined $result->{'returnbranch'} );
- }
-
# built-in default circulation rule
- $result->{'holdallowed'} = 2 unless ( defined $result->{'holdallowed'} );
- $result->{'hold_fulfillment_policy'} = 'any' unless ( defined $result->{'hold_fulfillment_policy'} );
- $result->{'returnbranch'} = 'homebranch' unless ( defined $result->{'returnbranch'} );
+ my $rules;
+ $rules->{holdallowed} = defined $holdallowed_rule
+ ? $holdallowed_rule->rule_value
+ : 2;
+ $rules->{hold_fulfillment_policy} = defined $hold_fulfillment_policy_rule
+ ? $hold_fulfillment_policy_rule->rule_value
+ : 'any';
+ $rules->{returnbranch} = defined $returnbranch_rule
+ ? $returnbranch_rule->rule_value
+ : 'homebranch';
- return $result;
+ return $rules;
}
=head2 AddReturn
}
my $item_unblessed = $item->unblessed;
- if ( $item->location eq 'PROC' ) {
- if ( C4::Context->preference("InProcessingToShelvingCart") ) {
- $item_unblessed->{location} = 'CART';
- }
- else {
- $item_unblessed->{location} = $item->permanent_location;
- }
-
- ModItem( $item_unblessed, $item->biblionumber, $item->itemnumber, { log_action => 0 } );
- }
-
# full item data, but no borrowernumber or checkout info (no issue)
my $hbr = GetBranchItemRule($item->homebranch, $itemtype)->{'returnbranch'} || "homebranch";
# get the proper branch to which to return the item
my $borrowernumber = $patron ? $patron->borrowernumber : undef; # we don't know if we had a borrower or not
my $patron_unblessed = $patron ? $patron->unblessed : {};
+ my $update_loc_rules = get_yaml_pref_hash('UpdateItemLocationOnCheckin');
+ map { $update_loc_rules->{$_} = $update_loc_rules->{$_}[0] } keys %$update_loc_rules; #We can only move to one location so we flatten the arrays
+ if ($update_loc_rules) {
+ if (defined $update_loc_rules->{_ALL_}) {
+ if ($update_loc_rules->{_ALL_} eq '_PERM_') { $update_loc_rules->{_ALL_} = $item->permanent_location; }
+ if ($update_loc_rules->{_ALL_} eq '_BLANK_') { $update_loc_rules->{_ALL_} = ''; }
+ if ( $item->location ne $update_loc_rules->{_ALL_}) {
+ $messages->{'ItemLocationUpdated'} = { from => $item->location, to => $update_loc_rules->{_ALL_} };
+ ModItem( { location => $update_loc_rules->{_ALL_} }, undef, $itemnumber );
+ }
+ }
+ else {
+ foreach my $key ( keys %$update_loc_rules ) {
+ if ( $update_loc_rules->{$key} eq '_PERM_' ) { $update_loc_rules->{$key} = $item->permanent_location; }
+ if ( $update_loc_rules->{$key} eq '_BLANK_') { $update_loc_rules->{$key} = '' ;}
+ if ( ($item->location eq $key && $item->location ne $update_loc_rules->{$key}) || ($key eq '_BLANK_' && $item->location eq '' && $update_loc_rules->{$key} ne '') ) {
+ $messages->{'ItemLocationUpdated'} = { from => $item->location, to => $update_loc_rules->{$key} };
+ ModItem( { location => $update_loc_rules->{$key} }, undef, $itemnumber );
+ last;
+ }
+ }
+ }
+ }
+
my $yaml = C4::Context->preference('UpdateNotForLoanStatusOnCheckin');
if ($yaml) {
$yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
MarkIssueReturned( $borrowernumber, $item->itemnumber, $return_date, $patron->privacy );
};
unless ( $@ ) {
- if ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue ) {
+ if ( C4::Context->preference('CalculateFinesOnReturn') && $is_overdue && !$item->itemlost ) {
_CalculateAndUpdateFine( { issue => $issue, item => $item_unblessed, borrower => $patron_unblessed, return_date => $return_date } );
}
} else {
);
$sth->execute( $item->itemnumber );
# if we have a reservation with valid transfer, we can set it's status to 'W'
- ShelfToCart( $item->itemnumber ) if ( C4::Context->preference("ReturnToShelvingCart") );
C4::Reserves::ModReserveStatus($item->itemnumber, 'W');
} else {
$messages->{'WrongTransfer'} = $tobranch;
$messages->{'WrongTransferItem'} = $item->itemnumber;
}
$validTransfert = 1;
- } else {
- ShelfToCart( $item->itemnumber ) if ( C4::Context->preference("ReturnToShelvingCart") );
}
# fix up the accounts.....
# fix up the overdues in accounts...
if ($borrowernumber) {
- my $fix = _FixOverduesOnReturn( $borrowernumber, $item->itemnumber, $exemptfine );
+ my $fix = _FixOverduesOnReturn( $borrowernumber, $item->itemnumber, $exemptfine, 'RETURNED' );
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->itemnumber...) failed!"; # zero is OK, check defined
if ( $issue and $issue->is_overdue ) {
=head2 _FixOverduesOnReturn
- &_FixOverduesOnReturn($borrowernumber, $itemnumber, $exemptfine);
+ &_FixOverduesOnReturn($borrowernumber, $itemnumber, $exemptfine, $status);
C<$borrowernumber> borrowernumber
C<$exemptfine> BOOL -- remove overdue charge associated with this issue.
+C<$status> ENUM -- reason for fix [ RETURNED, RENEWED, LOST, FORGIVEN ]
+
Internal function
=cut
sub _FixOverduesOnReturn {
- my ( $borrowernumber, $item, $exemptfine ) = @_;
+ my ( $borrowernumber, $item, $exemptfine, $status ) = @_;
unless( $borrowernumber ) {
warn "_FixOverduesOnReturn() not supplied valid borrowernumber";
return;
warn "_FixOverduesOnReturn() not supplied valid itemnumber";
return;
}
+ unless( $status ) {
+ warn "_FixOverduesOnReturn() not supplied valid status";
+ return;
+ }
- # check for overdue fine
- my $accountline = Koha::Account::Lines->search(
- {
- borrowernumber => $borrowernumber,
- itemnumber => $item,
- accounttype => 'FU'
- }
- )->next();
- return 0 unless $accountline; # no warning, there's just nothing to fix
+ my $schema = Koha::Database->schema;
- if ($exemptfine) {
- my $amountoutstanding = $accountline->amountoutstanding;
+ my $result = $schema->txn_do(
+ sub {
+ # check for overdue fine
+ my $accountlines = Koha::Account::Lines->search(
+ {
+ borrowernumber => $borrowernumber,
+ itemnumber => $item,
+ debit_type_code => 'OVERDUE',
+ status => 'UNRETURNED'
+ }
+ );
+ return 0 unless $accountlines->count; # no warning, there's just nothing to fix
- $accountline->accounttype('FFOR');
- $accountline->amountoutstanding(0);
+ my $accountline = $accountlines->next;
+ if ($exemptfine) {
+ my $amountoutstanding = $accountline->amountoutstanding;
- Koha::Account::Offset->new(
- {
- debit_id => $accountline->id,
- type => 'Forgiven',
- amount => $amountoutstanding * -1,
+ my $account = Koha::Account->new({patron_id => $borrowernumber});
+ my $credit = $account->add_credit(
+ {
+ amount => $amountoutstanding,
+ user_id => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef,
+ library_id => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
+ interface => C4::Context->interface,
+ type => 'forgiven',
+ item_id => $item
+ }
+ );
+
+ $credit->apply({ debits => [ $accountline ], offset_type => 'Forgiven' });
+
+ $accountline->status('FORGIVEN');
+
+ if (C4::Context->preference("FinesLog")) {
+ &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
+ }
+ } else {
+ $accountline->status($status);
}
- )->store();
- if (C4::Context->preference("FinesLog")) {
- &logaction("FINES", 'MODIFY',$borrowernumber,"Overdue forgiven: item $item");
+ return $accountline->store();
}
- } else {
- $accountline->accounttype('F');
- }
+ );
- return $accountline->store();
+ return $result;
}
=head2 _FixAccountForLostAndReturned
&_FixAccountForLostAndReturned($itemnumber, [$borrowernumber, $barcode]);
-Calculates the charge for a book lost and returned.
+Finds the most recent lost item charge for this item and refunds the borrower
+appropriatly, taking into account any payments or writeoffs already applied
+against the charge.
Internal function, not exported, called only by AddReturn.
# check for charge made for lost book
my $accountlines = Koha::Account::Lines->search(
{
- itemnumber => $itemnumber,
- accounttype => { -in => [ 'L', 'Rep', 'W' ] },
+ itemnumber => $itemnumber,
+ debit_type_code => 'LOST',
+ status => [ undef, { '<>' => 'RETURNED' } ]
},
{
order_by => { -desc => [ 'date', 'accountlines_id' ] }
return unless $accountlines->count > 0;
my $accountline = $accountlines->next;
my $total_to_refund = 0;
- my $account = Koha::Patrons->find( $accountline->borrowernumber )->account;
+
+ return unless $accountline->borrowernumber;
+ my $patron = Koha::Patrons->find( $accountline->borrowernumber );
+ return unless $patron; # Patron has been deleted, nobody to credit the return to
+
+ my $account = $patron->account;
# Use cases
if ( $accountline->amount > $accountline->amountoutstanding ) {
}
);
- # TODO: ->apply should just accept the accountline
- $credit->apply( { debits => $accountlines->reset } );
+ $credit->apply( { debits => [ $accountline ] } );
}
- # Manually set the accounttype
- $accountline->discard_changes->accounttype('LR');
+ # Update the account status
+ $accountline->discard_changes->status('RETURNED');
$accountline->store;
- ModItem( { paidfor => '' }, undef, $itemnumber, { log_action => 0 } );
-
if ( defined $account and C4::Context->preference('AccountAutoReconcile') ) {
$account->reconcile_balance;
}
# can be filled with available items. We can get the union of the sets simply
# by pushing all the elements onto an array and removing the duplicates.
my @reservable;
- my %borrowers;
- ITEM: foreach my $i (@itemnumbers) {
- my $item = Koha::Items->find($i)->unblessed;
- next if IsItemOnHoldAndFound($i);
- for my $b (@borrowernumbers) {
- my $borr = $borrowers{$b} //= Koha::Patrons->find( $b )->unblessed;
- next unless IsAvailableForItemLevelRequest($item, $borr);
- next unless CanItemBeReserved($b,$i);
-
- push @reservable, $i;
+ my %patrons;
+ ITEM: foreach my $itemnumber (@itemnumbers) {
+ my $item = Koha::Items->find( $itemnumber );
+ next if IsItemOnHoldAndFound( $itemnumber );
+ for my $borrowernumber (@borrowernumbers) {
+ my $patron = $patrons{$borrowernumber} //= Koha::Patrons->find( $borrowernumber );
+ next unless IsAvailableForItemLevelRequest($item, $patron);
+ next unless CanItemBeReserved($borrowernumber,$itemnumber);
+
+ push @reservable, $itemnumber;
if (@reservable >= @borrowernumbers) {
$resfound = 0;
last ITEM;
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 } );
- }
- _FixOverduesOnReturn( $borrowernumber, $itemnumber );
-
- # 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) {
-
- $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, $circ_library->branchcode, $patron_unblessed, 'is a renewal');
- }
+ my $schema = Koha::Database->schema;
+ $schema->txn_do(sub{
- 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),
+ if ( C4::Context->preference('CalculateFinesOnReturn') && $issue->is_overdue ) {
+ _CalculateAndUpdateFine( { issue => $issue, item => $item_unblessed, borrower => $patron_unblessed } );
+ }
+ _FixOverduesOnReturn( $borrowernumber, $itemnumber, undef, 'RENEWED' );
+
+ # 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) {
+
+ $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, $circ_library->branchcode, $patron_unblessed, 'is a renewal');
}
- );
- # 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;
- my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
- WHERE borrowernumber=?
- AND itemnumber=?"
- );
+ 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),
+ }
+ );
- $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
+ # 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;
+ my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
+ WHERE borrowernumber=?
+ AND itemnumber=?"
+ );
- # Update the renewal count on the item, and tell zebra to reindex
- $renews = $item_object->renewals + 1;
- ModItem( { renewals => $renews, onloan => $datedue->strftime('%Y-%m-%d %H:%M')}, $item_object->biblionumber, $itemnumber, { log_action => 0 } );
+ $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber );
- # Charge a new rental fee, if applicable
- my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
- if ( $charge > 0 ) {
- my $description = "Renewal of Rental Item " . $biblio->title . " " .$item_object->barcode;
- AddIssuingCharge($issue, $charge, $description);
- }
+ # Update the renewal count on the item, and tell zebra to reindex
+ $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 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 a new rental fee, if applicable
+ my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
+ if ( $charge > 0 ) {
+ AddIssuingCharge($issue, $charge, 'rent_renew');
}
- $charge += $accumulate_charge;
- }
- # Send a renewal slip according to checkout alert preferencei
- if ( C4::Context->preference('RenewalSendNotice') eq '1' ) {
- my $circulation_alert = 'C4::ItemCirculationAlertPreference';
- my %conditions = (
- branchcode => $branch,
- categorycode => $patron->categorycode,
- item_type => $itemtype,
- notification => 'CHECKOUT',
- );
- if ( $circulation_alert->is_enabled_for( \%conditions ) ) {
- SendCirculationAlert(
- {
- type => 'RENEWAL',
- item => $item_unblessed,
- borrower => $patron->unblessed,
- branch => $branch,
- }
- );
+ # 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 ) {
+ AddIssuingCharge( $issue, $accumulate_charge, 'rent_daily_renew' )
+ }
+ $charge += $accumulate_charge;
}
- }
- # Remove any OVERDUES related debarment if the borrower has no overdues
- if ( $patron
- && $patron->is_debarred
- && ! $patron->has_overdues
- && @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) }
- ) {
- DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
- }
+ # Send a renewal slip according to checkout alert preferencei
+ if ( C4::Context->preference('RenewalSendNotice') eq '1' ) {
+ my $circulation_alert = 'C4::ItemCirculationAlertPreference';
+ my %conditions = (
+ branchcode => $branch,
+ categorycode => $patron->categorycode,
+ item_type => $itemtype,
+ notification => 'CHECKOUT',
+ );
+ if ( $circulation_alert->is_enabled_for( \%conditions ) ) {
+ SendCirculationAlert(
+ {
+ type => 'RENEWAL',
+ item => $item_unblessed,
+ borrower => $patron->unblessed,
+ branch => $branch,
+ }
+ );
+ }
+ }
- unless ( C4::Context->interface eq 'opac' ) { #if from opac we are obeying OpacRenewalBranch as calculated in opac-renew.pl
- $branch = C4::Context->userenv ? C4::Context->userenv->{branch} : $branch;
- }
+ # Remove any OVERDUES related debarment if the borrower has no overdues
+ if ( $patron
+ && $patron->is_debarred
+ && ! $patron->has_overdues
+ && @{ GetDebarments({ borrowernumber => $borrowernumber, type => 'OVERDUES' }) }
+ ) {
+ DelUniqueDebarment({ borrowernumber => $borrowernumber, type => 'OVERDUES' });
+ }
- # Add the renewal to stats
- UpdateStats(
- {
- branch => $branch,
- type => 'renew',
- amount => $charge,
- itemnumber => $itemnumber,
- itemtype => $itemtype,
- location => $item_object->location,
- borrowernumber => $borrowernumber,
- ccode => $item_object->ccode,
+ unless ( C4::Context->interface eq 'opac' ) { #if from opac we are obeying OpacRenewalBranch as calculated in opac-renew.pl
+ $branch = C4::Context->userenv ? C4::Context->userenv->{branch} : $branch;
}
- );
- #Log the renewal
- logaction("CIRCULATION", "RENEWAL", $borrowernumber, $itemnumber) if C4::Context->preference("RenewalLog");
+ # Add the renewal to stats
+ UpdateStats(
+ {
+ branch => $branch,
+ type => 'renew',
+ amount => $charge,
+ itemnumber => $itemnumber,
+ itemtype => $itemtype,
+ location => $item_object->location,
+ borrowernumber => $borrowernumber,
+ ccode => $item_object->ccode,
+ }
+ );
+
+ #Log the renewal
+ logaction("CIRCULATION", "RENEWAL", $borrowernumber, $itemnumber) if C4::Context->preference("RenewalLog");
+ });
+
return $datedue;
}
=head2 AddIssuingCharge
- &AddIssuingCharge( $checkout, $charge, [$description] )
+ &AddIssuingCharge( $checkout, $charge, $type )
=cut
sub AddIssuingCharge {
- my ( $checkout, $charge, $description ) = @_;
+ my ( $checkout, $charge, $type ) = @_;
# FIXME What if checkout does not exist?
my $accountline = $account->add_debit(
{
amount => $charge,
- description => $description,
note => undef,
user_id => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef,
library_id => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef,
interface => C4::Context->interface,
- type => 'rent',
+ type => $type,
item_id => $checkout->itemnumber,
issue_id => $checkout->issue_id,
}
sub ReturnLostItem{
my ( $borrowernumber, $itemnum ) = @_;
-
MarkIssueReturned( $borrowernumber, $itemnum );
- my $patron = Koha::Patrons->find( $borrowernumber );
- my $item = Koha::Items->find($itemnum);
- my $old_note = ($item->paidfor && ($item->paidfor ne q{})) ? $item->paidfor.' / ' : q{};
- my @datearr = localtime(time);
- my $date = ( 1900 + $datearr[5] ) . "-" . ( $datearr[4] + 1 ) . "-" . $datearr[3];
- my $bor = $patron->firstname . ' ' . $patron->surname . ' ' . $patron->cardnumber;
- ModItem({ paidfor => $old_note."Paid for by $bor $date" }, undef, $itemnum);
}
if ( my $borrowernumber = $issues->{borrowernumber} ){
my $patron = Koha::Patrons->find( $borrowernumber );
- my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, C4::Context->preference('WhenLostForgiveFine'), 0); # 1, 0 = exemptfine, no-dropbox
+ my $fix = _FixOverduesOnReturn($borrowernumber, $itemnumber, C4::Context->preference('WhenLostForgiveFine'), 'LOST');
defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $itemnumber...) failed!"; # zero is OK, check defined
if (C4::Context->preference('WhenLostChargeReplacementFee')){