lp1846354 middle layer changes
authorJason Etheridge <jason@EquinoxInitiative.org>
Wed, 8 Jan 2020 14:03:28 +0000 (09:03 -0500)
committerChris Sharp <csharp@georgialibraries.org>
Wed, 18 Mar 2020 21:15:51 +0000 (17:15 -0400)
The ApplyPatronPenalty A/T Reactor will be modified to create a user message if
needed instead of setting the note field on the created penalty, and will set
the new usr_message field accordingly.

The API method open-ils.actor.user.penalty.note.update will be similarly
adjusted, though it may edit or create a user message as needed.

The API method open-ils.actor.user.penalty.apply will also be modified to
create user messages in lieu of setting a note field.  The sending_lib field
for such messages will be set to match the session's workstation library,
regardless of the org unit that actually gets applied to the penalty's org_unit
field.  The org_unit field will use the value as passed by the caller, and no
longer do the org_unit_ancestor_at_depth adjustment that happens today.

Both penalty.note.update and penalty.apply will set the editor and edit date
columns on any linked user messages to the current time and staff member for
any already existing message that has its title or message value modified.  The
read_date column will also be NULL'ed in such circumstances so that the message
will appear unread to the patron if public.

The react sub in Event.pm will be tweaked to explicitly set the pub field on
created user messages to true for Action/Trigger.

Signed-off-by: Jason Etheridge <jason@EquinoxInitiative.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Collections.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Event.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Trigger/Reactor/ApplyPatronPenalty.pm

index 9014d90..1c6a463 100644 (file)
@@ -1417,6 +1417,19 @@ sub get_my_org_path {
         $org_id );
 }
 
+__PACKAGE__->register_method(
+    method   => "get_my_org_ancestor_at_depth",
+    api_name => "open-ils.actor.org_unit.ancestor_at_depth.retrieve"
+);
+
+sub get_my_org_ancestor_at_depth {
+    my( $self, $client, $auth, $org_id, $depth ) = @_;
+    my $e = new_editor(authtoken=>$auth);
+    return $e->event unless $e->checkauth;
+    $org_id = $e->requestor->ws_ou unless defined $org_id;
+
+    return $apputils->org_unit_ancestor_at_depth( $org_id, $depth );
+}
 
 __PACKAGE__->register_method(
     method   => "patron_adv_search",
@@ -1880,7 +1893,13 @@ sub user_opac_vitals {
     $out->{"total_out"} = reduce { $a + $out->{$b} } 0, qw/out overdue/;
 
     my $unread_msgs = $e->search_actor_usr_message([
-        {usr => $user_id, read_date => undef, deleted => 'f'},
+        {usr => $user_id, read_date => undef, deleted => 'f',
+            'pub' => 't', # this is for the unread message count in the opac
+            '-or' => [
+                {stop_date => undef},
+                {stop_date => {'>' => 'now'}}
+            ],
+        },
         {idlist => 1}
     ]);
 
@@ -3002,7 +3021,9 @@ __PACKAGE__->register_method(
 );
 
 sub apply_penalty {
-    my($self, $conn, $auth, $penalty) = @_;
+    my($self, $conn, $auth, $penalty, $msg) = @_;
+
+    $msg ||= {};
 
     my $e = new_editor(authtoken=>$auth, xact => 1);
     return $e->die_event unless $e->checkauth;
@@ -3012,10 +3033,23 @@ sub apply_penalty {
 
     my $ptype = $e->retrieve_config_standing_penalty($penalty->standing_penalty) or return $e->die_event;
 
-    my $ctx_org =
-        (defined $ptype->org_depth) ?
-        $U->org_unit_ancestor_at_depth($penalty->org_unit, $ptype->org_depth) :
-        $penalty->org_unit;
+    my $ctx_org = $penalty->org_unit; # csp org_depth is now considered in the UI for the org drop-down menu
+
+    if (($msg->{title} || $msg->{message}) && ($msg->{title} ne '' || $msg->{message} ne '')) {
+        my $aum = Fieldmapper::actor::usr_message->new;
+
+        $aum->create_date('now');
+        $aum->sending_lib($e->requestor->ws_ou);
+        $aum->title($msg->{title});
+        $aum->usr($penalty->usr);
+        $aum->message($msg->{message});
+        $aum->pub($msg->{pub});
+
+        $aum = $e->create_actor_usr_message($aum)
+            or return $e->die_event;
+
+        $penalty->usr_message($aum->id);
+    }
 
     $penalty->org_unit($ctx_org);
     $penalty->staff($e->requestor->id);
@@ -3026,6 +3060,44 @@ sub apply_penalty {
 }
 
 __PACKAGE__->register_method(
+    method   => "modify_penalty",
+    api_name => "open-ils.actor.user.penalty.modify"
+);
+
+sub modify_penalty {
+    my($self, $conn, $auth, $penalty, $usr_msg) = @_;
+
+    my $e = new_editor(authtoken=>$auth, xact => 1);
+    return $e->die_event unless $e->checkauth;
+
+    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);
+
+    $usr_msg->editor($e->requestor->id);
+    $usr_msg->edit_date('now');
+
+    if ($usr_msg->isnew) {
+        $usr_msg = $e->create_actor_usr_message($usr_msg)
+            or return $e->die_event;
+        $penalty->usr_message($usr_msg->id);
+    } else {
+        $usr_msg = $e->update_actor_usr_message($usr_msg)
+            or return $e->die_event;
+    }
+
+    if ($penalty->isnew) {
+        $penalty = $e->create_actor_user_standing_penalty($penalty)
+            or return $e->die_event;
+    } else {
+        $penalty = $e->update_actor_user_standing_penalty($penalty)
+            or return $e->die_event;
+    }
+
+    $e->commit;
+    return 1;
+}
+
+__PACKAGE__->register_method(
     method   => "remove_penalty",
     api_name => "open-ils.actor.user.penalty.remove"
 );
@@ -3052,14 +3124,39 @@ sub update_penalty_note {
     my $e = new_editor(authtoken=>$auth, xact => 1);
     return $e->die_event unless $e->checkauth;
     for my $penalty_id (@$penalty_ids) {
-        my $penalty = $e->search_actor_user_standing_penalty( { id => $penalty_id } )->[0];
+        my $penalty = $e->search_actor_user_standing_penalty([
+            { id => $penalty_id },
+            {   flesh => 1,
+                flesh_fields => {aum => ['usr_message']}
+            }
+        ])->[0];
         if (! $penalty ) { 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);
 
-        $penalty->note( $note ); $penalty->ischanged( 1 );
+        my $aum = $penalty->usr_message();
+        if (!$aum) {
+            $aum = Fieldmapper::actor::usr_message->new;
+
+            $aum->create_date('now');
+            $aum->sending_lib($e->requestor->ws_ou);
+            $aum->title('');
+            $aum->usr($penalty->usr);
+            $aum->message($note);
+            $aum->pub(0);
+            $aum->isnew(1);
 
-        $e->update_actor_user_standing_penalty($penalty) or return $e->die_event;
+            $aum = $e->create_actor_usr_message($aum)
+                or return $e->die_event;
+
+            $penalty->usr_message($aum->id);
+            $penalty->ischanged(1);
+            $e->update_actor_user_standing_penalty($penalty) or return $e->die_event;
+        } else {
+            $aum = $e->retrieve_actor_usr_message($aum) or return $e->die_event;
+            $aum->message($note); $aum->ischanged(1);
+            $e->update_actor_usr_message($aum) or return $e->die_event;
+        }
     }
     $e->commit;
     return 1;
@@ -3129,6 +3226,12 @@ sub new_flesh_user {
         $fetch_penalties = 1;
     }
 
+    my $fetch_notes = 0;
+    if(grep {$_ eq 'notes'} @$fields) {
+        $fields = [grep {$_ ne 'notes'} @$fields];
+        $fetch_notes = 1;
+    }
+
     my $fetch_usr_act = 0;
     if(grep {$_ eq 'usr_activity'} @$fields) {
         $fields = [grep {$_ ne 'usr_activity'} @$fields];
@@ -3177,12 +3280,27 @@ sub new_flesh_user {
                     org_unit => $U->get_org_full_path($e->requestor->ws_ou)
                 },
                 {   flesh => 1,
-                    flesh_fields => {ausp => ['standing_penalty']}
+                    flesh_fields => {ausp => ['standing_penalty','usr_message']}
                 }
             ])
         );
     }
 
+    if($fetch_notes) {
+        # grab undeleted notes (now actor.usr_message_penalty) that have not hit their stop_date
+        $user->notes(
+            $e->search_actor_usr_message_penalty([
+                {   usr => $id,
+                    deleted => 'f',
+                    '-or' => [
+                        {stop_date => undef},
+                        {stop_date => {'>' => 'now'}}
+                    ],
+                }, {}
+            ])
+        );
+    }
+
     # retrieve the most recent usr_activity entry
     if ($fetch_usr_act) {
 
index b3a1fbe..dfb6b19 100644 (file)
@@ -487,8 +487,8 @@ sub put_into_collections {
     $pen->usr($user_id);
     $pen->standing_penalty(30); # PATRON_IN_COLLECTIONS
     $pen->staff($e->requestor->id);
-    $pen->note($fee_note) if $fee_note;
-    $U->simplereq('open-ils.actor', 'open-ils.actor.user.penalty.apply', $auth, $pen);
+    my $msg = { 'pub' => 0, 'title' => 'PATRON_IN_COLLECTIONS', 'message' => $fee_note };
+    $U->simplereq('open-ils.actor', 'open-ils.actor.user.penalty.apply', $auth, $pen, $msg);
 
     return OpenILS::Event->new('SUCCESS');
 }
index bd85e38..7d0a8cf 100644 (file)
@@ -209,6 +209,7 @@ sub react {
                         $usr_message->message( $message_template_output );
                         $usr_message->usr( $env->{usr_message}{usr}->id );
                         $usr_message->sending_lib( $env->{usr_message}{sending_lib}->id );
+                        $usr_message->pub('t');
 
                         if ($self->editor->xact_begin) {
                             if ($self->editor->create_actor_usr_message( $usr_message )) {
index 33e624e..10ee5f3 100644 (file)
@@ -60,7 +60,22 @@ sub handler {
     $penalty->usr($user->id);
     $penalty->org_unit($context_org);
     $penalty->standing_penalty($ptype->id);
-    $penalty->note($self->run_TT($env));
+
+    my $aum = Fieldmapper::actor::usr_message->new;
+    $aum->create_date('now');
+    $aum->sending_lib($context_org);
+    $aum->title('');
+    $aum->usr($penalty->usr);
+    $aum->message($self->run_TT($env));
+    $aum->pub(0);
+
+    $aum = $e->create_actor_usr_message($aum);
+    unless($aum) {
+        $e->rollback;
+        return 0;
+    }
+
+    $penalty->usr_message($aum->id);
 
     unless($e->create_actor_user_standing_penalty($penalty)) {
         $e->rollback;