jeff godin's idea: ml method to invalidate email addresses collab/senator/mark_email_inactive
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 12 Dec 2011 23:15:43 +0000 (18:15 -0500)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 12 Dec 2011 23:15:43 +0000 (18:15 -0500)
still needs:
    sql with upgrade script to add new CSP
    testing
    better documentation
    ???

Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/perlmods/lib/OpenILS/Utils/BadContact.pm [new file with mode: 0644]

index 03a20aa..3adf1f7 100644 (file)
@@ -34,6 +34,7 @@ use OpenILS::Application::Actor::Stage;
 
 use OpenILS::Utils::CStoreEditor qw/:funcs/;
 use OpenILS::Utils::Penalty;
+use OpenILS::Utils::BadContact;
 use List::Util qw/max reduce/;
 
 use UUID::Tiny qw/:std/;
@@ -379,6 +380,9 @@ sub update_patron {
        ( $new_patron, $evt ) = _add_survey_responses($session, $patron, $new_patron, $user_obj);
        return $evt if $evt;
 
+       ( $new_patron, $evt ) = _clear_badcontact_penalties($session, $patron, $new_patron, $user_obj);
+       return $evt if $evt;
+
        # re-update the patron if anything has happened to him during this process
        if($new_patron->ischanged()) {
                ( $new_patron, $evt ) = _update_patron($session, $new_patron, $user_obj);
@@ -876,6 +880,33 @@ sub _add_survey_responses {
        return ( $new_patron, undef );
 }
 
+sub _clear_badcontact_penalties {
+       my ($session, $patron, $new_patron, $user_obj) = @_;
+
+    return ($new_patron, undef) if $patron->email_address eq $new_patron->email_address;
+
+    my $e = new_editor(xact => 1);
+
+    # This ignores whether the caller of update_patron has any permission
+    # to remove this penalty, but this penalty no longer makes sense
+    # if an email address is changed (and the caller must have perms to do that)
+    # so the penalties should go away.
+
+    my $penalties_to_clear = $e->retrieve_actor_usr_standing_penalty([
+        {
+            "+csp" => {"name" => "INVALID_EMAIL_ADDRESS"},
+            "+ausp" => {"stop_date" => undef, "usr" => $new_patron->id}
+        },
+        {"join" => {"csp" => {}}}
+    ]) or return (undef, $e->die_event);
+
+    foreach (@$penalties_to_clear) {
+        $e->delete_actor_usr_standing_penalty($_) or return (undef, $e->die_event);
+    }
+
+    return ($new_patron, undef);
+}
+
 
 sub _create_stat_maps {
 
@@ -4364,4 +4395,23 @@ sub get_barcodes {
     }
 }
 
+sub mark_users_email_invalid {
+    my ($self, $conn, $auth, $email, $note, $penalty_ou) = @_;
+
+    # middle-layer call for "invalidate email" which 
+    # removes the bad email address, copying its contents to a patron 
+    # note, and institutes a standing penalty for "bad email" which 
+    # is cleared when the user is saved or optionally only when the 
+    # user is saved with an email address (or staff manually delete 
+    # the penalty).
+
+
+    my $e = new_editor(authtoken => $auth, xact => 1);
+    return $e->die_event unless $e->checkauth;
+
+    return OpenILS::Utils::BadContact->mark_users_email_invalid(
+        $e, $email, $note, $penalty_ou, $e->requestor->id
+    );
+}
+
 1;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/BadContact.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/BadContact.pm
new file mode 100644 (file)
index 0000000..b205ad8
--- /dev/null
@@ -0,0 +1,103 @@
+package OpenILS::Utils::BadContact;
+
+use strict;
+use warnings;
+
+use OpenILS::Event;
+use OpenILS::Utils::CStoreEditor;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Application::AppUtils;
+
+my $U = "OpenILS::Utils::AppUtils";
+
+# For users who match the given email address, remove the bad email
+# address, copying its contents to a patron note (or not, see OU setting),
+# and applying a standing penalty INVALID_EMAIL_ADDRESS (or not, see OU
+# setting).
+# Returns an event. SUCCESS if no problem.
+
+sub mark_users_email_invalid {
+    my ($class, $editor, $email, $note, $penalty_ou, $staff_id) = @_;
+
+    # users with matching e-mail address
+    my $users = $editor->search_actor_usr({
+        email_address => $email, deleted => "f"
+    }) or return $editor->die_event;
+
+    # waste no more time
+    return $editor->die_event(new OpenILS::Event("ACTOR_USER_NOT_FOUND"))
+        unless @$users;
+
+    # we'll use these two for caching OU settings
+    my $want_note = {};
+    my $want_penalty = {};
+
+    # we'll need this to apply user penalties (OU settings allowing)
+    my $penalty = $editor->retrieve_config_standing_penalty({
+        name => "INVALID_EMAIL_ADDRESS"
+    }) or return $editor->die_event;
+
+    my $user_counter = 0;
+
+    foreach (@$users) {
+        my $ou = $_->home_ou;
+        if ($editor->requestor) {
+            next unless $editor->allowed("UPDATE_USER", $ou);
+        }
+
+        if (not exists($want_note->{$ou})) {
+            $want_note->{$ou} =
+                $U->ou_ancestor_setting_value(
+                    $ou, "circ.patron_invalid_email_save_in_note", $editor
+                ) || 0;
+        }
+        if (not exists($want_penalty->{$ou})) {
+            $want_penalty->{$ou} =
+                $U->ou_ancestor_setting_value(
+                    $ou, "circ.patron_invalid_email_apply_penalty", $editor
+                ) || 0;
+        }
+
+        if ($want_note->{$ou}) {
+            my $note = new Fieldmapper::actor::usr_note;
+            $note->usr($_->id);
+            $note->creator($staff_id);
+
+            # XXX what's the best way to make thing configurable and enable
+            # i18n?  Best I can come up with is an opensrf setting, but
+            # that seems wrong.
+            $note->title("Invalidated Email Address");
+            $note->value($_->email_address);
+
+            $editor->create_actor_usr_note($note) or return $editor->die_event;
+        }
+
+        if ($want_penalty->{$ou}) {
+            my $usr_penalty = new Fieldmapper::actor::usr_standing_penalty;
+            $usr_penalty->usr($_->id);
+            $usr_penalty->org_unit($penalty_ou || $ou);
+            $usr_penalty->standing_penalty($penalty->id);
+            $usr_penalty->staff($staff_id);
+
+            $editor->create_actor_usr_standing_penalty($usr_penalty) or
+                return $editor->die_event;
+        }
+
+        $_->clear_email_address;
+        $editor->update_actor_usr($_) or return $editor->die_event;
+
+        $user_counter++;
+    }
+
+    $editor->commit;
+
+    return new OpenILS::Event(
+        "SUCCESS", payload => {users_changed => $user_counter}
+    );
+}
+
+sub mark_users_phone_invalid {
+    # XXX TODO, but along the same lines as mark_users_email_invalid() above?
+}
+
+1;