use OpenILS::Application::AppUtils;
use OpenSRF::Utils qw/:datetime/;
use OpenILS::Event;
+use OpenSRF::Utils::Cache;
use OpenSRF::Utils::Logger qw(:logger);
use OpenILS::Utils::CStoreEditor q/:funcs/;
use OpenILS::Const qw/:const/;
# Do not publish methods here. This code is shared across apps.
# -----------------------------------------------------------------
+# return org setting value, using the value found in $cache if available.
+my $settings_cache;
+sub get_cached_ou_setting {
+ my ($class, $org_id, $setting, $token) = @_;
+ $token //= '';
+ my $key = join('.', 'YAOUS_CACHE', $token, $org_id, $setting);
+
+ $settings_cache ||= OpenSRF::Utils::Cache->new('global');
+ my $value = $settings_cache->get_cache($key);
+ if (!defined($value)) {
+ $value = $U->ou_ancestor_setting_value($org_id, $setting);
+ $settings_cache->put_cache($key => $value);
+ }
+
+ return $value;
+}
+
# -----------------------------------------------------------------
# Voids (or zeros) overdue fines on the given circ. if a backdate is
}
sub extend_grace_period {
- my($class, $circ_lib, $due_date, $grace_period, $e, $h) = @_;
+ my($class, $circ_lib, $due_date, $grace_period, $e, $h, $cache_token) = @_;
if ($grace_period >= 86400) { # Only extend grace periods greater than or equal to a full day
my $parser = DateTime::Format::ISO8601->new;
my $due_dt = $parser->parse_datetime( cleanse_ISO8601( $due_date ) );
my $due = $due_dt->epoch;
- my $grace_extend = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend');
+ my $grace_extend = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend', $cache_token);
$e = new_editor() if (!$e);
$h = $e->retrieve_actor_org_unit_hours_of_operation($circ_lib) if (!$h);
if ($grace_extend and $h) {
} else {
# Extra nice grace periods
# AKA, merge closed dates trailing the grace period into the grace period
- my $grace_extend_into_closed = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend.into_closed');
+ my $grace_extend_into_closed = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend.into_closed', $cache_token);
$due += 86400 if $grace_extend_into_closed;
- my $grace_extend_all = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend.all');
+ my $grace_extend_all = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend.all', $cache_token);
if ( $grace_extend_all ) {
# Start checking the day after the item was due
sub generate_fines {
my ($class, $args) = @_;
my $circs = $args->{circs};
+ my $cache_token = $args->{cache_token};
return unless $circs and @$circs;
my $e = $args->{editor};
# if a client connection is passed in, this will be chatty like
$logger->info( "Potential first billing for circ ".$c->id );
$last_fine = $due;
- $grace_period = extend_grace_period($class, $c->$circ_lib_method,$c->$due_date_method,$grace_period,undef,$hoo{$c->$circ_lib_method});
+ $grace_period = extend_grace_period($class, $c->$circ_lib_method,$c->$due_date_method,$grace_period,undef,$hoo{$c->$circ_lib_method},$cache_token);
}
return if ($last_fine > $now);
my $recurring_fine = int($c->$recurring_fine_method * 100);
my $max_fine = int($c->max_fine * 100);
- my $skip_closed_check = $U->ou_ancestor_setting_value(
+ my $skip_closed_check = $class->get_cached_ou_setting(
$c->$circ_lib_method, 'circ.fines.charge_when_closed');
$skip_closed_check = $U->is_true($skip_closed_check);
- my $truncate_to_max_fine = $U->ou_ancestor_setting_value(
+ my $truncate_to_max_fine = $class->get_cached_ou_setting(
$c->$circ_lib_method, 'circ.fines.truncate_to_max_fine');
$truncate_to_max_fine = $U->is_true($truncate_to_max_fine);
use strict;
use warnings;
-use OpenSRF::Utils::JSON;
+use Getopt::Long;
use OpenSRF::System;
use OpenSRF::Utils::SettingsClient;
use OpenSRF::MultiSession;
-my $config = shift || die "bootstrap config required\n";
-my $lockfile = shift || "/tmp/generate_fines-LOCK";
-my $grace = shift;
+my $help;
+my $osrf_config = '/openils/conf/opensrf_core.xml';
+my $lockfile = '/tmp/generate_fines-LOCK';
+my $parallel = 1; # default to opensrf.xml value
-if (defined($grace)) {
- die "Grace period is now defined in the database. It should not be passed to the fine generator.";
+GetOptions(
+ 'help' => \$help,
+ 'osrf-config=s' => \$osrf_config,
+ 'lockfile=s' => \$lockfile,
+ 'parallel=i' => \$parallel,
+) || die "\nSee --help for more\n";
+
+
+# Support legacy (pre-get-opt) argument passing with warnings.
+my $legacy_config = shift;
+if ($legacy_config) {
+ warn "Loading opensrf config: $legacy_config.\n".
+ "Use --osrf-config instead to silence this warning\n";
+ $osrf_config = $legacy_config;
}
-
+
+my $legacy_lockfile = shift;
+if ($legacy_lockfile) {
+ warn "Loading lockfile: $legacy_lockfile.\n".
+ "Use --lockfile instead to silence this warning\n";
+ $lockfile = $legacy_lockfile;
+}
+
+sub help {
+ print <<HELP;
+
+Batch fine generator
+
+$0 --osrf-config $osrf_config --lockfile $lockfile --parallel 3
+
+Options
+
+ --osrf-config [/openils/conf/opensrf_core.xml]
+ OpenSRF config file.
+
+ --lockfile [/tmp/generate_fines-LOCK]
+ Full path to lock file
+
+ --parallel
+ Number of parallel fine generator processes to run.
+ When set, this overrides the value from opensrf.xml
+
+ --verbose
+ Print process counts
+HELP
+
+ exit(0);
+}
+
+help() if $help;
+
+# If a lockfile exists and the PID in the file is in fact running, exit.
+# If the lockfile references a dead PID, just replace it.
+
if (-e $lockfile) {
open(F,$lockfile);
my $pid = <F>;
close F;
}
-open(F, ">$lockfile");
+open(F, ">$lockfile") or die "Cannot open $lockfile: $!\n";
print F $$;
close F;
-OpenSRF::System->bootstrap_client( config_file => $config );
+OpenSRF::System->bootstrap_client( config_file => $osrf_config );
my $settings = OpenSRF::Utils::SettingsClient->new;
-my $parallel = $settings->config_value( fine_generator => 'parallel' ) || 1;
+$parallel = $settings->config_value( fine_generator => 'parallel' ) || 1;
if ($parallel == 1) {
my $r = OpenSRF::AppSession
->create( 'open-ils.storage' )
- ->request( 'open-ils.storage.action.circulation.overdue.generate_fines' );
+ ->request( 'open-ils.storage.action.circulation.overdue.generate_fines', undef, $$ );
while (!$r->complete) { $r->recv };
my $r = $storage->request('open-ils.storage.action.circulation.overdue.id_list');
while (my $resp = $r->recv(timeout => 600)) {
my $circ_id = $resp->content;
- $multi_generator->request( 'open-ils.storage.action.circulation.overdue.generate_fines', $circ_id );
+ $multi_generator->request( 'open-ils.storage.action.circulation.overdue.generate_fines', $circ_id, $$ );
}
$storage->disconnect();
$multi_generator->session_wait(1);