$year, $mon, $mday, $hour, $min, $sec
);
+ $self->method_lookup( 'open-ils.storage.transaction.begin')->run($client);
+
($statuses) = $self->method_lookup('open-ils.storage.direct.config.copy_status.search.holdable.atomic')->run('t');
($locations) = $self->method_lookup('open-ils.storage.direct.asset.copy_location.search.holdable.atomic')->run('t');
prev_check_time => { '<=' => $expire_threshold },
},
{ order_by => 'request_time,prev_check_time' } );
- push @$holds, @{
- $self->method_lookup('open-ils.storage.direct.action.hold_request.search.atomic')
+ push @$holds, $self->method_lookup('open-ils.storage.direct.action.hold_request.search')
->run(
{ capture_time => undef,
prev_check_time => undef },
- { order_by => 'request_time' } ) };
+ { order_by => 'request_time' } );
}
} catch Error with {
my $e = shift;
die "Could not retrieve uncaptured hold requests:\n\n$e\n";
};
- $_->clear_current_copy for (@$holds);
-
for my $hold (@$holds) {
- my $copies;
-
- my @captured_copies = [ map {$_->current_copy} @$holds ];
+ try {
+ my $copies;
- if (0) { # hold isn't check-expired
- # get the copies from the hold-map
- # and filter on "avialable"
- } else {
$copies = $self->metarecord_hold_capture($hold) if ($hold->hold_type eq 'M');
$copies = $self->title_hold_capture($hold) if ($hold->hold_type eq 'T');
$copies = $self->volume_hold_capture($hold) if ($hold->hold_type eq 'V');
$copies = $self->copy_hold_capture($hold) if ($hold->hold_type eq 'C');
- }
- next unless (ref $copies);
+ $client->respond("Processing hold ".$hold->id."...\n");
+ unless (ref $copies) {
+ $client->respond("\tNo copies available for targeting!\n");
+ next;
+ }
- my @good_copies;
- for my $c (@$copies) {
- next if ( grep {$c->id == $_} @captured_copies);
- push @good_copies, $c;
- }
+ my @good_copies;
+ for my $c (@$copies) {
+ next if ( grep {$c->id == $hold->current_copy} @good_copies);
+ push @good_copies, $c if ($c);
+ }
+
+ $client->respond("\t".scalar(@good_copies)." (non-current) copies available for targeting...\n");
+
+ my $old_best = $hold->current_copy;
+ $hold->clear_current_copy;
+
+ if (!scalar(@good_copies)) {
+ if ( $old_best && grep {$c->id == $hold->current_copy} @$copies ) {
+ $client->respond("\tPushing current_copy back onto the targeting list\n");
+ push @good_copies, $self->method_lookup('open-ils.storage.direct.asset.copy.retrieve')->run( $old_best );
+ } else {
+ $client->respond("\tcurrent_copy is no longer available for targeting... NEXT!\n");
+ next;
+ }
+ }
- my $prox_list;
- $$prox_list[0] = [grep {$_->circ_lib == $hold->pickup_lib } @$copies];
- $copies = [grep {$_->circ_lib != $hold->pickup_lib } @$copies];
+ my $prox_list;
+ $$prox_list[0] = [grep {$_->circ_lib == $hold->pickup_lib } @good_copies];
+ $copies = [grep {$_->circ_lib != $hold->pickup_lib } @good_copies];
- my $best = $self->choose_nearest_copy($hold, $prox_list);
+ my $best = $self->choose_nearest_copy($hold, $prox_list);
- if (!$best) {
- $prox_list = $self->create_prox_list( $hold->pickup_lib, $copies );
- $best = $self->choose_nearest_copy($hold, $prox_list);
- }
+ if (!$best) {
+ $prox_list = $self->create_prox_list( $hold->pickup_lib, $copies );
+ $best = $self->choose_nearest_copy($hold, $prox_list);
+ }
- if ($best) {
- $hold->current_copy( $best->id );
- }
+ if ($old_best) {
+ # hold wasn't fulfilled, record the fact
+
+ $client->respond("\tHold was not (but should have been) fulfilled by ".$old_best->id.".\n");
+ my $ufh = new Fieldmapper::action::unfulfilled_hold_list;
+ $ufh->hold( $hold->id );
+ $ufh->current_copy( $old_best->id );
+ $ufh->circ_lib( $old_best->circ_lib );
+ $self->method_lookup('open-ils.storage.direct.action.unfulfilled_hold_list.create')->run( $ufh );
+ }
- $hold->prev_check_time( 'now');
- my ($r) = $self->method_lookup('open-ils.storage.direct.action.hold_request.update')->run( $hold );
+ if ($best) {
+ $hold->current_copy( $best->id );
+ $client->respond("\tTargeting copy ".$best->id." for hold fulfillment.\n");
+ }
- $client->respond("Processed hold ".$hold->id.". ".
- do{ $hold->current_copy ? "Targeting copy ".$hold->current_copy." for capture." : ''; }.
- "\n"
- );
+ $hold->prev_check_time( 'now' );
+ my ($r) = $self->method_lookup('open-ils.storage.direct.action.hold_request.update')->run( $hold );
+
+ $client->respond("\tProcessing of hold ".$hold->id." complete.\n");
+ $self->method_lookup('open-ils.storage.transaction.commit')->run;
+
+ } otherwise {
+ my $e = shift;
+ $client->respond("\tProcessing of hold ".$hold->id." failed!.\n\t\t$e\n");
+ $self->method_lookup('open-ils.storage.transaction.rollback')->run;
+ };
}
return undef;
}
my @copies = grep { $_->holdable == 1 and $_->ref == 0 } @$cps;
for (my $i = 0; $i < @copies; $i++) {
+ next unless $copies[$i];
- my $cn = $cache{cns}{$copies[0]->call_number};
+ my $cn = $cache{cns}{$copies[$i]->call_number};
my $rec = $cache{titles}{$cn->record};
$copies[$i] = undef if ($copies[$i] && !grep{ $copies[$i]->status eq $_->id}@$statuses);
$copies[$i] = undef if ($copies[$i] && !grep{ $copies[$i]->location eq $_->id}@$locations);
return unless ($count);
- my ($old_maps) = $self->method_lookup('open-ils.storage.direct.action.hold_copy_map.search.hold.atomic')->run( $hold->id );
+ my @old_maps = $self->method_lookup('open-ils.storage.direct.action.hold_copy_map.search.hold')->run( $hold->id );
- $self->method_lookup('open-ils.storage.direct.action.hold_copy_map.batch.delete')->run(@$old_maps );
+ $self->method_lookup('open-ils.storage.direct.action.hold_copy_map.batch.delete')->run(@old_maps );
my @maps;
for my $c (@copies) {
try {
my @recs = map {$_->record}
- @{$self->method_lookup('open-ils.storage.direct.metabib.record_descriptor.search.atomic')
- ->run( record => $titles, item_type => [split '', $hold->holdable_formats] )};
+ $self->method_lookup('open-ils.storage.direct.metabib.record_descriptor.search')
+ ->run( record => $titles, item_type => [split '', $hold->holdable_formats] );
$titles = [];
($titles) = $self->method_lookup('open-ils.storage.direct.biblio.record_entry.search.id.atomic')->run( \@recs );
FROM money.payment p
JOIN pg_class c ON (p.tableoid = c.oid);
+CREATE OR REPLACE VIEW money.transaction_billing_summary AS
+ SELECT xact,
+ note AS last_billing_note,
+ MAX(billing_ts) AS last_billing_ts,
+ SUM(COALESCE(amount,0)) AS total_owed
+ FROM money.billing
+ WHERE voided IS FALSE
+ GROUP BY xact,note
+ ORDER BY MAX(billing_ts);
+
+CREATE OR REPLACE VIEW money.transaction_payment_summary AS
+ SELECT xact,
+ note AS last_payment_note,
+ MAX(payment_ts) as last_payment_ts,
+ SUM(COALESCE(amount,0)) AS total_paid
+ FROM money.payment
+ WHERE voided IS FALSE
+ GROUP BY xact,note
+ ORDER BY MAX(payment_ts);
CREATE OR REPLACE VIEW money.billable_xact_summary AS
SELECT xact.id AS id,
xact.usr AS usr,
xact.xact_start AS xact_start,
xact.xact_finish AS xact_finish,
- SUM(COALESCE(credit.amount,0)) AS total_paid,
- MAX(credit.payment_ts) AS last_payment_ts,
- SUM(COALESCE(debit.amount,0)) AS total_owed,
- MAX(debit.billing_ts) AS last_billing_ts,
- COALESCE(debit.note,'') AS last_billing_note,
- SUM(COALESCE(debit.amount,0) - COALESCE(credit.amount,0)) AS balance_owed,
+ credit.total_paid,
+ credit.last_payment_ts,
+ credit.last_payment_note,
+ debit.total_owed,
+ debit.last_billing_ts,
+ debit.last_billing_note,
+ COALESCE(debit.total_owed,0) - COALESCE(credit.total_paid,0) AS balance_owed,
p.relname AS xact_type
- FROM money.billable_xact xact
- JOIN pg_class p ON (xact.tableoid = p.oid)
- LEFT JOIN money.billing debit ON (xact.id = debit.xact AND debit.voided IS FALSE)
- LEFT JOIN money.payment credit ON (xact.id = credit.xact AND credit.voided IS FALSE)
+ FROM money.billable_xact xact,
+ pg_class p,
+ money.transaction_billing_summary debit,
+ money.transaction_payment_summary credit
WHERE xact.xact_finish IS NULL
- GROUP BY 1,2,3,4,9,11;
+ AND xact.tableoid = p.oid
+ AND xact.id = debit.xact
+ AND xact.id = credit.xact;
CREATE OR REPLACE VIEW money.usr_summary AS
SELECT usr,