Added two library settings.
"Assess Billing When Marked Long-Overdue"
Making it an option to bill patrons when marking LOD.
"Continue Overdue Billing When Marked Long-Overdue"
Allowing the system to continue to generate overdue fines
after the circulation has been marked LONGOVERDUE.
Altered the select query to respect that setting.
Edited the query in fm_IDL so that Long overdues
are still listed in the OPAC for the patrons even
without billing. If there are bills, they are listed
at the bottom under the fine category.
Signed-off-by: blake <blake@mobiusconsortium.org>
Conflicts:
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
CASE
WHEN (
((fine_interval >= '1 day' AND due_date < 'today') OR (fine_interval < '1 day' AND due_date < 'now'))
- AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+ AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR (stop_fines IN ('LONGOVERDUE') AND ID NOT IN(SELECT xact FROM money.billing WHERE xact=acirc.id)))
+
) THEN 1
ELSE 0
END
SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LOST') THEN 1 ELSE 0 END) AS lost,
SUM( CASE WHEN stop_fines = 'CLAIMSRETURNED' THEN 1 ELSE 0 END) AS claims_returned,
- SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE') THEN 1 ELSE 0 END) AS long_overdue
- FROM action.circulation
+ SUM( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE' AND ID IN(SELECT xact FROM money.billing WHERE xact=acirc.id)) THEN 1 ELSE 0 END) AS long_overdue
+ FROM action.circulation acirc
WHERE checkin_time IS NULL
GROUP BY 1
</oils_persist:source_definition>
CASE
WHEN (
((fine_interval >= '1 day' AND due_date < 'today') OR (fine_interval < '1 day' AND due_date < 'now'))
- AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE'))
+ AND (stop_fines IS NULL OR stop_fines NOT IN ('LOST','CLAIMSRETURNED','LONGOVERDUE') OR (stop_fines IN ('LONGOVERDUE') AND ID NOT IN(SELECT xact FROM money.billing WHERE xact=acirc.id)))
) THEN id::TEXT
ELSE '0'
END
STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LOST') THEN id::TEXT ELSE '0' END,',') AS lost,
STRING_AGG( CASE WHEN stop_fines = 'CLAIMSRETURNED' THEN id::TEXT ELSE '0' END,',') AS claims_returned,
- STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE') THEN id::TEXT ELSE '0' END,',') AS long_overdue
- FROM action.circulation
+ STRING_AGG( CASE WHEN (xact_finish IS NULL AND stop_fines = 'LONGOVERDUE' AND ID IN(SELECT xact FROM money.billing WHERE xact=acirc.id)) THEN id::TEXT ELSE '0' END,',') AS long_overdue
+ FROM action.circulation acirc
WHERE checkin_time IS NULL
GROUP BY 1
</oils_persist:source_definition>
->run($auth => $user_id);
return $out if (defined($U->event_code($out)));
- $out->{"total_out"} = reduce { $a + $out->{$b} } 0, qw/out overdue/;
+ $out->{"total_out"} = reduce { $a + $out->{$b} } 0, qw/out overdue long_overdue/;
my $unread_msgs = $e->search_actor_usr_message([
{usr => $user_id, read_date => undef, deleted => 'f'},
return $class->set_item_lost_or_lod(
$e, $copy_id,
perm => 'SET_CIRC_LONG_OVERDUE',
- status => 16, # Long Overdue
- ous_proc_fee => 'circ.longoverdue_materials_processing_fee',
- ous_void_od => 'circ.void_overdue_on_longoverdue',
+ status => OILS_COPY_STATUS_LONG_OVERDUE,
+ ous_proc_fee => OILS_SETTING_LONG_OVERDUE_PROCESSING_FEE,
+ ous_void_od => OILS_SETTING_VOID_OVERDUE_ON_LONG_OVERDUE,
bill_type => 10,
bill_fee_type => 11,
bill_note => 'Long Overdue Materials',
bill_fee_note => 'Long Overdue Materials Processing Fee',
event => 'COPY_MARKED_LONG_OVERDUE',
- stop_fines => 'LONGOVERDUE',
- at_hook => 'longoverdue'
+ stop_fines => OILS_STOP_FINES_LONGOVERDUE,
+ at_hook => 'longoverdue',
+ ous_assess_billing => OILS_SETTING_LONG_OVERDUE_ASSESS_BILLING
);
}
$owning_lib, $args{ous_proc_fee}, $e) || 0;
my $void_overdue = $U->ou_ancestor_setting_value(
$owning_lib, $args{ous_void_od}, $e) || 0;
+ my $lod_assess_billing = $U->ou_ancestor_setting_value(
+ $owning_lib, $args{ous_assess_billing}, $e);
+ $lod_assess_billing = 1 unless defined $lod_assess_billing;
# ---------------------------------------------------------------------
- # move the copy into LOST status
+ # move the copy into LOST/LONGOVERDUE status
$copy->status($args{status});
$copy->editor($e->requestor->id);
$copy->edit_date('now');
$e->update_asset_copy($copy) or return $e->die_event;
- my $price = $U->get_copy_price($e, $copy, $copy->call_number);
+ # ---------------------------------------------------------------------
+ # Assess billing only when proceeding as "Lost"
+ # or if this is lod and circ.longoverdue.assess_billing is true *or null
+
+ if( !( ($args{status} == OILS_COPY_STATUS_LONG_OVERDUE) && !$lod_assess_billing) ) {
- if( $price > 0 ) {
- my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e,
- $price, $args{bill_type}, $args{bill_note}, $circ->id);
- return $evt if $evt;
- }
+ my $price = $U->get_copy_price($e, $copy, $copy->call_number);
+
+ if( $price > 0 ) {
+ my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e,
+ $price, $args{bill_type}, $args{bill_note}, $circ->id);
+ return $evt if $evt;
+ }
- # ---------------------------------------------------------------------
- # if there is a processing fee, charge that too
- if( $proc_fee > 0 ) {
- my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e,
- $proc_fee, $args{bill_fee_type}, $args{bill_fee_note}, $circ->id);
- return $evt if $evt;
+ # ---------------------------------------------------------------------
+ # if there is a processing fee, charge that too
+ if( $proc_fee > 0 ) {
+ my $evt = OpenILS::Application::Circ::CircCommon->create_bill($e,
+ $proc_fee, $args{bill_fee_type}, $args{bill_fee_note}, $circ->id);
+ return $evt if $evt;
+ }
}
# ---------------------------------------------------------------------
- # mark the circ as lost and stop the fines
+ # mark the circ as lost/longoverdue and stop the fines
$circ->stop_fines($args{stop_fines});
$circ->stop_fines_time('now') unless $circ->stop_fines_time;
$e->update_action_circulation($circ) or return $e->die_event;
- # ---------------------------------------------------------------------
- # zero out overdue fines on this circ if configured
- if( $void_overdue ) {
- my $evt = OpenILS::Application::Circ::CircCommon->void_or_zero_overdues($e, $circ, {force_zero => 1, note => "System: OVERDUE REVERSED for " . $args{bill_note} . " Processing"});
- return $evt if $evt;
+ if( !( ($args{status} == OILS_COPY_STATUS_LONG_OVERDUE) && !$lod_assess_billing) ) {
+ # ---------------------------------------------------------------------
+ # zero out overdue fines on this circ if configured
+ if( $void_overdue ) {
+ my $evt = OpenILS::Application::Circ::CircCommon->void_or_zero_overdues($e, $circ, {force_zero => 1, note => "System: OVERDUE REVERSED for " . $args{bill_note} . " Processing"});
+ return $evt if $evt;
+ }
}
-
my $evt = OpenILS::Application::Circ::CircCommon->reopen_xact($e, $circ->id);
return $evt if $evt;
my $sql = <<" SQL";
SELECT $contents
- FROM $c_t
- WHERE stop_fines IS NULL
+ FROM $c_t acirc
+ WHERE
+ (
+ (stop_fines IS NULL)
+ OR
+ (stop_fines='LONGOVERDUE' AND
+ COALESCE (
+ (SELECT value::BOOLEAN FROM
+ actor.org_unit_ancestor_setting
+ ('circ.longoverdue.continue_overdue_billing',acirc.circ_lib)
+ ),FALSE
+ )
+ )
+ )
$fines_filter
AND due_date < ( CURRENT_TIMESTAMP - grace_period )
AND fine_interval < ?::INTERVAL
# Settings
# ---------------------------------------------------------------------
econst OILS_SETTING_LOST_PROCESSING_FEE => 'circ.lost_materials_processing_fee';
+econst OILS_SETTING_LONG_OVERDUE_PROCESSING_FEE => 'circ.longoverdue_materials_processing_fee';
econst OILS_SETTING_DEF_ITEM_PRICE => 'cat.default_item_price';
econst OILS_SETTING_MIN_ITEM_PRICE => 'circ.min_item_price';
econst OILS_SETTING_MAX_ITEM_PRICE => 'circ.max_item_price';
econst OILS_SETTING_ORG_BOUNCED_EMAIL => 'org.bounced_emails';
econst OILS_SETTING_CHARGE_LOST_ON_ZERO => 'circ.charge_lost_on_zero';
econst OILS_SETTING_VOID_OVERDUE_ON_LOST => 'circ.void_overdue_on_lost';
+econst OILS_SETTING_VOID_OVERDUE_ON_LONG_OVERDUE => 'circ.void_overdue_on_longoverdue';
econst OILS_SETTING_HOLD_SOFT_STALL => 'circ.hold_stalling.soft';
econst OILS_SETTING_HOLD_HARD_STALL => 'circ.hold_stalling.hard';
econst OILS_SETTING_HOLD_SOFT_BOUNDARY => 'circ.hold_boundary.soft';
econst OILS_SETTING_LOST_IMMEDIATELY_AVAILABLE => 'circ.lost_immediately_available';
econst OILS_SETTING_BLOCK_HOLD_FOR_EXPIRED_PATRON => 'circ.holds.expired_patron_block';
econst OILS_SETTING_GENERATE_OVERDUE_ON_LOST_RETURN => 'circ.lost.generate_overdue_on_checkin';
+econst OILS_SETTING_LONG_OVERDUE_ASSESS_BILLING => 'circ.longoverdue.assess_billing';
checkin_time => undef,
'-or' => [
{stop_fines => undef},
- {stop_fines => {'not in' => ['LOST','CLAIMSRETURNED','LONGOVERDUE']}}
+ {stop_fines => {'not in' => ['LOST','CLAIMSRETURNED']}}
],
}
},
'When granted, newly added lineitem identifiers will propagate to linked bib records', 'ppl', 'description')),
( 548, 'ACQ_SET_LINEITEM_IDENTIFIER', oils_i18n_gettext(548,
'Allows staff to change the lineitem identifier', 'ppl', 'description')),
- ( 549, 'COPY_STATUS_LONGOVERDUE.override', oils_i18n_gettext(549,
+ ( 549, 'COPY_STATUS_LONG_OVERDUE.override', oils_i18n_gettext(549,
'Allows the user to check-in long-overdue items, prompting ' ||
'long-overdue check-in processing', 'ppl', 'code')),
( 550, 'SET_CIRC_LONG_OVERDUE', oils_i18n_gettext(550,
'circ.max_accept_return_of_longoverdue',
'coust',
'description'
+ )
+), (
+ 'circ.longoverdue.assess_billing',
+ 'finance', 'bool',
+ oils_i18n_gettext(
+ 'circ.longoverdue.assess_billing',
+ 'Assess Billing When Marked Long-Overdue',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'circ.longoverdue.assess_billing',
+ 'When an item is marked long overdue a bill for the item will be ' ||
+ 'assesed unless this setting is false. The default is true. If false ' ||
+ 'void overdue setting will be ignored and processing fee will be ignored',
+ 'coust',
+ 'description'
+ )
+), (
+ 'circ.longoverdue.continue_overdue_billing',
+ 'finance', 'bool',
+ oils_i18n_gettext(
+ 'circ.longoverdue.continue_overdue_billing',
+ 'Continue Overdue Billing When Marked Long-Overdue',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'circ.longoverdue.continue_overdue_billing',
+ 'When an item is marked long overdue, overdues are halted. ' ||
+ 'A setting of true here will allow the overdues to continue ' ||
+ 'until another condition is met.',
+ 'coust',
+ 'description'
)
+
);
-- mark long-overdue reactor
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (
+ 'circ.longoverdue.assess_billing',
+ 'finance',
+ oils_i18n_gettext(
+ 'circ.longoverdue.assess_billing',
+ 'Assess Billing When Marked Long-Overdue',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'circ.longoverdue.assess_billing',
+ 'When an item is marked long overdue, a bill for the item will be ' ||
+ 'assessed unless this setting is false. The default is true. If false, ' ||
+ '"Void Overdue Fines When Items are Marked Long-Overdue" and "Long-Overdue'||
+ ' Materials Processing Fee" settings will be ignored.',
+ 'coust',
+ 'description'
+ ), 'bool'
+)
+;
+
+INSERT INTO config.org_unit_setting_type ( name, grp, label, description, datatype ) VALUES (
+ 'circ.longoverdue.continue_overdue_billing',
+ 'finance',
+ oils_i18n_gettext(
+ 'circ.longoverdue.continue_overdue_billing',
+ 'Continue Overdue Billing When Marked Long-Overdue',
+ 'coust',
+ 'label'
+ ),
+ oils_i18n_gettext(
+ 'circ.longoverdue.continue_overdue_billing',
+ 'When an item is marked long overdue, overdues are halted. ' ||
+ 'A setting of true here will allow the overdues to continue ' ||
+ 'until another condition is met.',
+ 'coust',
+ 'description'
+ ), 'bool'
+ )
+ ;
+
+UPDATE PERMISSION.PERM_LIST SET CODE='COPY_STATUS_LONG_OVERDUE.override' WHERE CODE='COPY_STATUS_LONGOVERDUE.override';
+
+
+
+COMMIT;
--- /dev/null
+*New Library Setting*
+**Finances: Assess Billing When Marked Long-Overdue - When an item is marked long overdue a bill for the item will be assesed unless this setting is false. The default is true. If false, void overdue setting will be ignored and processing fee will be ignored
+**Finances: Continue Overdue Billing When Marked Long-Overdue - When an item is marked long overdue, overdues are halted. A setting of true here will allow the overdues to continue until another condition is met.
5) Click *Modify Copies*, then confirm the action.
+Mark an Item Long Overdue
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*Marking an item Long Overdue*
+
+Once an item has been overdue for a configurable amount of time, Evergreen will mark the item long overdue in the borrowing patron’s account. This will be done automatically through a Notification/Action Trigger. When the item is marked long overdue, several actions will take place:
+
+. The item will go into the status of “Long Overdue”
+
+. The item will be moved to the “Lost, Claimed Returned, Long Overdue, Has Unpaid Billings” section of the Items Out screen in the patron’s account
+
+. The accrual of overdue fines will be stopped
+
+Optionally the patron can be billed for the item price, a long overdue processing fee, and any overdue fines can be voided from the account. Patrons can also be sent a notification that the item was marked long overdue.
+
+image::media/long_overdue1.jpg[Patron Account-Long Overdue]
+
+
+*Checking in a Long Overdue item*
+
+If an item that has been marked long overdue is checked in, an alert will appear on the screen informing the staff member that the item was long overdue. Once checked in, the item will go into the status of “In process”. Optionally, the item price and long overdue processing fee can be voided and overdue fines can be reinstated on the patron’s account. If the item is checked in at a library other than its home library, a library setting controls whether the item can immediately fill a hold or circulate, or if it needs to be sent to its home library for processing.
+
+image::media/long_overdue2.jpg[Long Overdue Checkin]
+
+*Notification/Action Triggers*
+
+Evergreen has two sample Notification/Action Triggers that are related to marking items long overdue. The sample triggers are configured for 6 months. These triggers can be configured for any amount of time according to library policy and will need to be activated for use.
+
+* Sample Triggers
+
+** 6 Month Auto Mark Long-Overdue—will mark an item long overdue after the configured period of time
+
+** 6 Month Long Overdue Notice—will send patron notification that an item has been marked long overdue on their account
+
+*Library Settings*
+
+The following Library Settings enable you to set preferences related to long overdue items:
+
+* *Circulation: Long-Overdue Check-In Interval Uses Last Activity Date* —Use the long-overdue last-activity date instead of the due_date to determine whether the item has been checked out too long to perform long-overdue check-in processing. If set, the system will first check the last payment time, followed by the last billing time, followed by the due date. See also circ.max_accept_return_of_longoverdue
+
+* *Circulation: Long-Overdue Items Usable on Checkin* —Long-overdue items are usable on checkin instead of going "home" first
+
+* *Circulation: Long-Overdue Max Return Interval* —Long-overdue check-in processing (voiding fees, re-instating overdues, etc.) will not take place for items that have been overdue for (or have last activity older than) this amount of time
+
+* *Circulation: Restore Overdues on Long-Overdue Item Return*
+
+* *Circulation: Void Long-Overdue item Billing When Returned*
+
+* *Circulation: Void Processing Fee on Long-Overdue Item Return*
+
+* *Finances: Leave transaction open when long overdue balance equals zero* —Leave transaction open when long-overdue balance equals zero. This leaves the lost copy on the patron record when it is paid
+
+* *Finances: Long-Overdue Materials Processing Fee*
+
+* *Finances: Void Overdue Fines When Items are Marked Long-Overdue*
+
+* *Finances: Assess Billing When Marked Long-Overdue* -Optionally skip billing price of item
+
+* *Finances: Continue Overdue Billing When Marked Long-Overdue*
+
+
+*Permissions to use this Feature*
+
+The following permissions are related to this feature:
+
+* COPY_STATUS_LONG_OVERDUE.override
+
+** Allows the user to check-in long-overdue items thus removing the long-overdue status on the item