From 10fbdd8a9c1578948be516c666887e8f34e8c316 Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 4 Mar 2009 22:02:20 +0000 Subject: [PATCH] moved mark-lost logic into cat/assetcommon and some transaction mgmt into circ/circcommon for non-published, shared access git-svn-id: svn://svn.open-ils.org/ILS/trunk@12406 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../OpenILS/Application/Cat/AssetCommon.pm | 72 +++++++++ .../src/perlmods/OpenILS/Application/Circ.pm | 142 +----------------- .../OpenILS/Application/Circ/CircCommon.pm | 108 +++++++++++++ 3 files changed, 184 insertions(+), 138 deletions(-) create mode 100644 Open-ILS/src/perlmods/OpenILS/Application/Circ/CircCommon.pm diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Cat/AssetCommon.pm b/Open-ILS/src/perlmods/OpenILS/Application/Cat/AssetCommon.pm index 29258c6012..6de5738c0a 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Cat/AssetCommon.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Cat/AssetCommon.pm @@ -9,6 +9,7 @@ use OpenILS::Utils::Fieldmapper; use OpenILS::Const qw/:const/; use OpenSRF::AppSession; use OpenILS::Event; +use OpenILS::Application::Circ::CircCommon; my $U = 'OpenILS::Application::AppUtils'; @@ -402,3 +403,74 @@ sub copy_perm_org { $logger->debug("using copy perm org $org"); return $org; } + + +sub set_item_lost { + my($class, $e, $copy_id) = @_; + + my $copy = $e->retrieve_asset_copy([ + $copy_id, + {flesh => 1, flesh_fields => {'acp' => ['call_number']}}]) + or return $e->die_event; + + my $owning_lib = + ($copy->call_number->id == OILS_PRECAT_CALL_NUMBER) ? + $copy->circ_lib : $copy->call_number->owning_lib; + + my $circ = $e->search_action_circulation( + {checkin_time => undef, target_copy => $copy->id} )->[0] + or return $e->die_event; + + $e->allowed('SET_CIRC_LOST', $circ->circ_lib) or return $e->die_event; + + return OpenILS::Event->new('COPY_MARKED_LOST') + if $copy->status == OILS_COPY_STATUS_LOST; + + # --------------------------------------------------------------------- + # fetch the related org settings + my $proc_fee = $U->ou_ancestor_setting_value( + $owning_lib, OILS_SETTING_LOST_PROCESSING_FEE, $e) || 0; + my $void_overdue = $U->ou_ancestor_setting_value( + $owning_lib, OILS_SETTING_VOID_OVERDUE_ON_LOST, $e) || 0; + + # --------------------------------------------------------------------- + # move the copy into LOST status + $copy->status(OILS_COPY_STATUS_LOST); + $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); + + if( $price > 0 ) { + my $evt = OpenILS::Application::Circ::CircCommon->create_bill( + $e, $price, 3, 'Lost Materials', $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, 4, 'Lost Materials Processing Fee', $circ->id); + return $evt if $evt; + } + + # --------------------------------------------------------------------- + # mark the circ as lost and stop the fines + $circ->stop_fines(OILS_STOP_FINES_LOST); + $circ->stop_fines_time('now') unless $circ->stop_fines_time; + $e->update_action_circulation($circ) or return $e->die_event; + + # --------------------------------------------------------------------- + # void all overdue fines on this circ if configured + if( $void_overdue ) { + my $evt = OpenILS::Application::Circ::CircCommon->void_overdues($e, $circ); + return $evt if $evt; + } + + my $evt = OpenILS::Application::Circ::CircCommon->reopen_xact($e, $circ->id); + return $evt if $evt; + + return undef; +} diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm index 9762db962f..2b9762afc8 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ.pm @@ -11,6 +11,7 @@ use OpenILS::Application::Circ::HoldNotify; use OpenILS::Application::Circ::Money; use OpenILS::Application::Circ::NonCat; use OpenILS::Application::Circ::CopyLocations; +use OpenILS::Application::Circ::CircCommon; use DateTime; use DateTime::Format::ISO8601; @@ -27,6 +28,7 @@ use OpenILS::Utils::Editor; use OpenILS::Utils::CStoreEditor q/:funcs/; use OpenILS::Const qw/:const/; use OpenSRF::Utils::SettingsClient; +use OpenILS::Application::Cat::AssetCommon; my $apputils = "OpenILS::Application::AppUtils"; my $U = $apputils; @@ -273,149 +275,13 @@ sub new_set_circ_lost { $e->allowed('SET_CIRC_LOST', $circ->circ_lib) or return $e->die_event; - return OpenILS::Event->new('COPY_MARKED_LOST') - if $copy->status == OILS_COPY_STATUS_LOST; - - # --------------------------------------------------------------------- - # fetch the related org settings - my $proc_fee = $U->ou_ancestor_setting_value( - $owning_lib, OILS_SETTING_LOST_PROCESSING_FEE, $e) || 0; - my $void_overdue = $U->ou_ancestor_setting_value( - $owning_lib, OILS_SETTING_VOID_OVERDUE_ON_LOST, $e) || 0; - - # --------------------------------------------------------------------- - # move the copy into LOST status - $copy->status(OILS_COPY_STATUS_LOST); - $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); - - if( $price > 0 ) { - my $evt = create_bill($e, $price, 3, 'Lost Materials', $circ->id); - return $evt if $evt; - } - - # --------------------------------------------------------------------- - # if there is a processing fee, charge that too - if( $proc_fee > 0 ) { - my $evt = create_bill($e, $proc_fee, 4, 'Lost Materials Processing Fee', $circ->id); - return $evt if $evt; - } - - # --------------------------------------------------------------------- - # mark the circ as lost and stop the fines - $circ->stop_fines(OILS_STOP_FINES_LOST); - $circ->stop_fines_time('now') unless $circ->stop_fines_time; - $e->update_action_circulation($circ) or return $e->die_event; - - # --------------------------------------------------------------------- - # void all overdue fines on this circ if configured - if( $void_overdue ) { - my $evt = void_overdues($e, $circ); - return $evt if $evt; - } - - my $evt = reopen_xact($e, $circ->id); + my $evt = OpenILS::Application::Cat::AssetCommon->set_item_lost($e, $copy->id); return $evt if $evt; $e->commit; return 1; } -sub reopen_xact { - my($e, $xactid) = @_; - - # ----------------------------------------------------------------- - # make sure the transaction is not closed - my $xact = $e->retrieve_money_billable_transaction($xactid) - or return $e->die_event; - - if( $xact->xact_finish ) { - my ($mbts) = $U->fetch_mbts($xactid, $e); - if( $mbts->balance_owed != 0 ) { - $logger->info("* re-opening xact $xactid, orig xact_finish is ".$xact->xact_finish); - $xact->clear_xact_finish; - $e->update_money_billable_transaction($xact) - or return $e->die_event; - } - } - - return undef; -} - - -sub create_bill { - my( $e, $amount, $btype, $type, $xactid ) = @_; - - $logger->info("The system is charging $amount [$type] on xact $xactid"); - - # ----------------------------------------------------------------- - # now create the billing - my $bill = Fieldmapper::money::billing->new; - $bill->xact($xactid); - $bill->amount($amount); - $bill->billing_type($type); - $bill->btype($btype); - $bill->note('SYSTEM GENERATED'); - $e->create_money_billing($bill) or return $e->die_event; - - return undef; -} - - - -# ----------------------------------------------------------------- -# Voids overdue fines on the given circ. if a backdate is -# provided, then we only void back to the backdate -# ----------------------------------------------------------------- -sub void_overdues { - my( $e, $circ, $backdate ) = @_; - - my $bill_search = { - xact => $circ->id, - btype => 1 - }; - - if( $backdate ) { - # ------------------------------------------------------------------ - # Fines for overdue materials are assessed up to, but not including, - # one fine interval after the fines are applicable. Here, we add - # one fine interval to the backdate to ensure that we are not - # voiding fines that were applicable before the backdate. - # ------------------------------------------------------------------ - - # if there is a raw time component (e.g. from postgres), - # turn it into an interval that interval_to_seconds can parse - my $duration = $circ->fine_interval; - $duration =~ s/(\d{2}):(\d{2}):(\d{2})/$1 h $2 m $3 s/o; - my $interval = OpenSRF::Utils->interval_to_seconds($duration); - - my $date = DateTime::Format::ISO8601->parse_datetime($backdate); - $backdate = $U->epoch2ISO8601($date->epoch + $interval); - $logger->info("applying backdate $backdate in overdue voiding"); - $$bill_search{billing_ts} = {'>=' => $backdate}; - } - - my $bills = $e->search_money_billing($bill_search); - - for my $bill (@$bills) { - next if $U->is_true($bill->voided); - $logger->info("voiding overdue bill ".$bill->id); - $bill->voided('t'); - $bill->void_time('now'); - $bill->voider($e->requestor->id); - my $n = $bill->note || ""; - $bill->note("$n\nSystem: VOIDED FOR BACKDATE"); - $e->update_money_billing($bill) or return $e->die_event; - } - - return undef; -} - - - __PACKAGE__->register_method( method => "set_circ_claims_returned", @@ -457,7 +323,7 @@ sub set_circ_claims_returned { if( $backdate ) { # make it look like the circ stopped at the cliams returned time $circ->stop_fines_time(clense_ISO8601($backdate)); - my $evt = void_overdues($e, $circ, $backdate); + my $evt = OpenILS::Application::Circ::CircCommon->void_overdues($e, $circ, $backdate); return $evt if $evt; } diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/CircCommon.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/CircCommon.pm new file mode 100644 index 0000000000..ee20693192 --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/CircCommon.pm @@ -0,0 +1,108 @@ +package OpenILS::Application::Circ::CircCommon; +use strict; use warnings; +use DateTime; +use DateTime::Format::ISO8601; +use OpenILS::Application::AppUtils; +use OpenSRF::Utils qw/:datetime/; +use OpenILS::Event; +use OpenSRF::Utils::Logger qw(:logger); +use OpenILS::Utils::CStoreEditor q/:funcs/; +use OpenILS::Const qw/:const/; + +my $U = "OpenILS::Application::AppUtils"; + +# ----------------------------------------------------------------- +# Do not publish methods here. This code is shared across apps. +# ----------------------------------------------------------------- + + +# ----------------------------------------------------------------- +# Voids overdue fines on the given circ. if a backdate is +# provided, then we only void back to the backdate +# ----------------------------------------------------------------- +sub void_overdues { + my($class, $e, $circ, $backdate) = @_; + + my $bill_search = { + xact => $circ->id, + btype => 1 + }; + + if( $backdate ) { + # ------------------------------------------------------------------ + # Fines for overdue materials are assessed up to, but not including, + # one fine interval after the fines are applicable. Here, we add + # one fine interval to the backdate to ensure that we are not + # voiding fines that were applicable before the backdate. + # ------------------------------------------------------------------ + + # if there is a raw time component (e.g. from postgres), + # turn it into an interval that interval_to_seconds can parse + my $duration = $circ->fine_interval; + $duration =~ s/(\d{2}):(\d{2}):(\d{2})/$1 h $2 m $3 s/o; + my $interval = OpenSRF::Utils->interval_to_seconds($duration); + + my $date = DateTime::Format::ISO8601->parse_datetime($backdate); + $backdate = $U->epoch2ISO8601($date->epoch + $interval); + $logger->info("applying backdate $backdate in overdue voiding"); + $$bill_search{billing_ts} = {'>=' => $backdate}; + } + + my $bills = $e->search_money_billing($bill_search); + + for my $bill (@$bills) { + next if $U->is_true($bill->voided); + $logger->info("voiding overdue bill ".$bill->id); + $bill->voided('t'); + $bill->void_time('now'); + $bill->voider($e->requestor->id); + my $n = $bill->note || ""; + $bill->note("$n\nSystem: VOIDED FOR BACKDATE"); + $e->update_money_billing($bill) or return $e->die_event; + } + + return undef; +} + + +sub reopen_xact { + my($class, $e, $xactid) = @_; + + # ----------------------------------------------------------------- + # make sure the transaction is not closed + my $xact = $e->retrieve_money_billable_transaction($xactid) + or return $e->die_event; + + if( $xact->xact_finish ) { + my ($mbts) = $U->fetch_mbts($xactid, $e); + if( $mbts->balance_owed != 0 ) { + $logger->info("* re-opening xact $xactid, orig xact_finish is ".$xact->xact_finish); + $xact->clear_xact_finish; + $e->update_money_billable_transaction($xact) + or return $e->die_event; + } + } + + return undef; +} + + +sub create_bill { + my($class, $e, $amount, $btype, $type, $xactid) = @_; + + $logger->info("The system is charging $amount [$type] on xact $xactid"); + + # ----------------------------------------------------------------- + # now create the billing + my $bill = Fieldmapper::money::billing->new; + $bill->xact($xactid); + $bill->amount($amount); + $bill->billing_type($type); + $bill->btype($btype); + $bill->note('SYSTEM GENERATED'); + $e->create_money_billing($bill) or return $e->die_event; + + return undef; +} + +1; -- 2.43.2