plugged in the new and improved in-db penalty calculation
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 23 Nov 2008 15:32:00 +0000 (15:32 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 23 Nov 2008 15:32:00 +0000 (15:32 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@11307 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm
Open-ILS/src/perlmods/OpenILS/Utils/Penalty.pm

index 6b5038e..3b3d073 100644 (file)
@@ -2730,39 +2730,37 @@ __PACKAGE__->register_method(
        api_name        => "open-ils.actor.user.penalties.update");
 
 sub update_penalties {
-       my( $self, $conn, $auth, $user_id ) = @_;
+       my($self, $conn, $auth, $user_id) = @_;
        my $e = new_editor(authtoken=>$auth, xact => 1);
        return $e->die_event unless $e->checkauth;
     my $user = $e->retrieve_actor_user($user_id) or return $e->die_event;
     return $e->die_event unless $e->allowed('UPDATE_USER', $user->home_ou);
-    my $evt = OpenILS::Utils::Penalty->calculate_penalties($e, $user_id);
+    my $evt = OpenILS::Utils::Penalty->calculate_penalties($e, $user_id, $e->requestor->ws_ou);
     return $evt if $evt;
     $e->commit;
     return 1;
 }
 
+
 __PACKAGE__->register_method(
        method  => "apply_penalty",
        api_name        => "open-ils.actor.user.penalty.apply");
 
 sub apply_penalty {
-       my($self, $conn, $auth, $user_id, $penalty_name) = @_;
+       my($self, $conn, $auth, $penalty) = @_;
        my $e = new_editor(authtoken=>$auth, xact => 1);
        return $e->die_event unless $e->checkauth;
-    my $user = $e->retrieve_actor_user($user_id) or return $e->die_event;
+    my $user = $e->retrieve_actor_user(penalty->usr) or return $e->die_event;
     return $e->die_event unless $e->allowed('UPDATE_USER', $user->home_ou);
 
-    my $penalty = $e->search_config_standing_penalty({name => $penalty_name})->[0]
-        or return $e->die_event;
-
     # is it already applied?
     return 1 if $e->search_actor_user_standing_penalty(
-        {usr => $user_id, standing_penalty => $penalty->id})->[0];
+        {   usr => $penalty->usr, 
+            standing_penalty => $penalty->standing_penalty,
+            org_unit => $penalty->org_unit
+        })->[0];
 
-    my $newp = Fieldmapper::actor::user_standing_penalty->new;
-    $newp->standing_penalty($penalty->id);
-    $newp->usr($user_id);
-    $e->create_actor_user_standing_penalty($newp) or return $e->die_event;
+    $e->create_actor_user_standing_penalty($penalty) or return $e->die_event;
     $e->commit;
     return 1;
 }
index 65d44fb..d4942d5 100644 (file)
@@ -835,9 +835,9 @@ sub run_patron_permit_scripts {
 
         my $patron_events = $result->{events};
 
-        OpenILS::Utils::Penalty->calculate_penalties($self->editor, undef, $self->patron);
+        OpenILS::Utils::Penalty->calculate_penalties($self->editor, $self->patron->id, $self->circ_lib);
         my $mask = ($self->is_renewal) ? 'RENEW' : 'CIRC';
-        my $penalties = OpenILS::Utils::penalty->retrieve_penalties($self->editor, $patronid, $mask);
+        my $penalties = OpenILS::Utils::Penalty->retrieve_penalties($self->editor, $patronid, $self->circ_lib, $mask);
 
         push( @allevents, OpenILS::Event->new($_)) for (@$penalties, @$patron_events);
     }
@@ -1176,7 +1176,7 @@ sub do_checkout {
     # Update the patron penalty info in the DB.  Run it for permit-overrides 
     # since the penalties are not updated during the permit phase
     # ------------------------------------------------------------------------------
-    $U->update_patron_penalties_nonblock(patronid => $self->patron->id) if $self->permit_override;
+    OpenILS::Utils::Penalty->calculate_penalties($self->editor, $self->patron->id, $self->circ_lib);
 
     my $record = $U->record_to_mvr($self->title) unless $self->is_precat;
     $self->push_events(
@@ -1756,7 +1756,7 @@ sub do_checkin {
             unless @{$self->events};
     }
 
-    $U->update_patron_penalties_nonblock(patronid => $self->patron->id) if $self->is_checkin;
+    OpenILS::Utils::Penalty->calculate_penalties($self->editor, $self->patron->id, $self->circ_lib);
     $self->checkin_flesh_events;
     return;
 }
index 7c5aa6b..9e5670b 100644 (file)
@@ -27,6 +27,7 @@ use Data::Dumper;
 use OpenILS::Event;
 use OpenSRF::Utils::Logger qw/:logger/;
 use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Utils::Penalty;
 
 __PACKAGE__->register_method(
        method  => "make_payments",
@@ -192,12 +193,11 @@ sub make_payments {
 
        $apputils->commit_db_session($session);
 
-       # ------------------------------------------------------------------------------
-       # Update the patron penalty info in the DB
-       # ------------------------------------------------------------------------------
-       $U->update_patron_penalties_nonblock(patronid  => $userid);
+    $client->respond_complete(1);      
 
-       $client->respond_complete(1);   
+       $e = new_editor(xact => 1);
+    $evt = OpenILS::Utils::Penalty->calculate_penalties($e, $userid, $drawer);
+    $e->commit unless $evt;
 
        return undef;
 }
@@ -379,31 +379,28 @@ sub billing_items_create {
        my( $self, $client, $login, $billing ) = @_;
 
        my $e = new_editor(authtoken => $login, xact => 1);
-       return $e->event unless $e->checkauth;
-       return $e->event unless $e->allowed('CREATE_BILL');
+       return $e->die_event unless $e->checkauth;
+       return $e->die_event unless $e->allowed('CREATE_BILL');
 
        my $xact = $e->retrieve_money_billable_transaction($billing->xact)
-               or return $e->event;
+               or return $e->die_event;
 
        # if the transaction was closed, re-open it
        if($xact->xact_finish) {
                $xact->clear_xact_finish;
                $e->update_money_billable_transaction($xact)
-                       or return $e->event;
+                       or return $e->die_event;
        }
 
        my $amt = $billing->amount;
        $amt =~ s/\$//og;
        $billing->amount($amt);
 
-       $e->create_money_billing($billing) or return $e->event;
+       $e->create_money_billing($billing) or return $e->die_event;
+    my $evt = OpenILS::Utils::Penalty->calculate_penalties($e, $xact->usr, $e->requestor->ws_ou);
+    return $evt if $evt;
        $e->commit;
 
-       # ------------------------------------------------------------------------------
-       # Update the patron penalty info in the DB
-       # ------------------------------------------------------------------------------
-       $U->update_patron_penalties_nonblock(patronid  => $xact->usr);
-
        return $billing->id;
 }
 
@@ -449,9 +446,8 @@ sub void_bill {
            return $evt if $evt;
     }
 
+    OpenILS::Utils::Penalty->calculate_penalties($e, $_, $e->requestor->ws_ou) for keys %users;
        $e->commit;
-    # update the penalties for each affected user
-       $U->update_patron_penalties_nonblock(patronid  => $_) for keys %users;
        return 1;
 }
 
index 2a9683c..5128842 100644 (file)
@@ -15,100 +15,39 @@ my $U = "OpenILS::Application::AppUtils";
 
 # calculate and update the well-known penalties
 sub calculate_penalties {
-    my($class, $e, $user_id, $user) = @_;
+    my($class, $e, $user_id, $context_org) = @_;
 
-    $user = $user || $e->retrieve_actor_user($user_id);
-    $user_id = $user->id;
-    my $grp_id = (ref $user->profile) ? $user->profile->id : $user->profile;
+    my $penalties = $e->json_query({from => ['actor.calculate_system_penalties',$user_id, $context_org]});
 
-    my $penalties = $e->search_actor_user_standing_penalty({usr => $user_id});
-    my $stats = $class->collect_user_stats($e, $user_id);
-    my $overdue = $stats->{overdue};
-    my $mon_owed = $stats->{money_owed};
-    my $thresholds = $class->get_group_penalty_thresholds($e, $grp_id);
+    for my $pen_obj (@$penalties) {
 
-    $logger->info("patron $user_id in group $grp_id has $overdue overdue circulations and owes $mon_owed");
+        next if grep { # leave duplicate penalties in place
+            $_->{org_unit} == $pen_obj->{org_unit} and
+            $_->{standing_penalty} == $pen_obj->{standing_penalty} and
+            ($_->{id} || '') ne ($pen_obj->{id} || '') } @$penalties;
 
-    for my $thresh (@$thresholds) {
-        my $evt;
+        if(defined $pen_obj->{id}) {
+            $e->delete_actor_user_standing_penalty($pen_obj->{id}) 
+                or return $e->die_event;
 
-        if($thresh->penalty == OILS_PENALTY_PATRON_EXCEEDS_FINES) {
-            $evt = $class->check_apply_penalty(
-                $e, $user_id, $penalties, OILS_PENALTY_PATRON_EXCEEDS_FINES, $thresh->threshold, $mon_owed);
-            return $evt if $evt;
+        } else {
+            my $newp = Fieldmapper::actor::user_standing_penalty->new;
+            $newp->$_($pen_obj->{$_}) for keys %$pen_obj;
+            $e->create_actor_user_standing_penalty($newp)
+                or return $e->die_event;
         }
-
-        if($thresh->penalty == OILS_PENALTY_PATRON_EXCEEDS_OVERDUE_COUNT) {
-            $evt = $class->check_apply_penalty(
-                $e, $user_id, $penalties, OILS_PENALTY_PATRON_EXCEEDS_OVERDUE_COUNT, $thresh->threshold, $overdue);
-            return $evt if $evt;
-        }
-    }
-}
-
-# if a given penalty does not already exist in the DB, this creates it.  
-# If it does exist and should not, this removes it.
-sub check_apply_penalty {
-    my($class, $e, $user_id, $all_penalties, $penalty_id, $threshold, $value) = @_;
-    my ($existing) = grep { $_->standing_penalty == $penalty_id } @$all_penalties;
-
-    # penalty threshold has been exceeded and needs to be added
-    if($value >= $threshold and not $existing) {
-        my $newp = Fieldmapper::actor::user_standing_penalty->new;
-        $newp->standing_penalty($penalty_id);
-        $newp->usr($user_id);
-        $e->create_actor_user_standing_penalty($newp) or return $e->die_event;
-
-    # patron is within penalty range and existing penalty must be removed
-    } elsif($value < $threshold and $existing) {
-        $e->delete_actor_user_standing_penalty($existing)
-            or return $e->die_event;
     }
 
     return undef;
 }
 
-
-sub collect_user_stats {
-    my($class, $e, $user_id) = @_;
-
-    my $stor_ses = $U->start_db_session();
-       my $money_owed = $stor_ses->request(
-        'open-ils.storage.actor.user.total_owed', $user_id)->gather(1);
-    my $checkouts = $stor_ses->request(
-           'open-ils.storage.actor.user.checked_out.count', $user_id)->gather(1);
-       $U->rollback_db_session($stor_ses);
-
-    return {
-        overdue => $checkouts->{overdue} || 0, 
-        money_owed => $money_owed || 0
-    };
-}
-
-# get the ranged set of penalties for a give group
-# XXX this could probably benefit from a stored proc
-sub get_group_penalty_thresholds {
-    my($class, $e, $grp_id) = @_;
-    my @thresholds;
-    my $cur_grp = $grp_id;
-    do {
-        my $thresh = $e->search_permission_grp_penalty_threshold({grp => $cur_grp});
-        for my $t (@$thresh) {
-            push(@thresholds, $t) unless (grep { $_->name eq $t->name } @thresholds);
-        }
-    } while(defined ($cur_grp = $e->retrieve_permission_grp_tree($cur_grp)->parent));
-    
-    return \@thresholds;
-}
-
-
 # any penalties whose block_list has an item from @fatal_mask will be sorted
 # into the fatal_penalties set.  Others will be sorted into the info_penalties set
 sub retrieve_penalties {
-    my($class, $e, $user_id, @fatal_mask) = @_;
+    my($class, $e, $user_id, $context_org, @fatal_mask) = @_;
 
     my $penalties = $e->search_actor_user_standing_penalty([
-        {usr => $user_id},
+        {usr => $user_id, org_unit => $U->get_org_ancestors($context_org)},
         {flesh => 1, flesh_fields => {ausp => ['standing_penalty']}}
     ]);