Online Renewal - First stab at adding erenew to Ecard.pm
authorTerran McCanna <tmccanna@georgialibraries.org>
Mon, 29 Aug 2022 16:24:12 +0000 (12:24 -0400)
committerJason Stephenson <jstephenson@cwmars.org>
Tue, 29 Nov 2022 18:50:58 +0000 (13:50 -0500)
Signed-off-by: Terran McCanna <tmccanna@georgialibraries.org>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Ecard.pm

index 1b16c94..238fc87 100644 (file)
@@ -15,50 +15,92 @@ use Digest::MD5 qw(md5_hex);
 $Data::Dumper::Indent = 0;
 my $U = 'OpenILS::Application::AppUtils';
 
-my @api_fields = (
-    {name => 'vendor_username', required => 1},
-    {name => 'vendor_password', required => 1},
-    {name => 'first_given_name', class => 'au', required => 1},
-    {name => 'second_given_name', class => 'au'},
-    {name => 'family_name', class => 'au', required => 1},
-    {name => 'suffix', class => 'au'},
-    {name => 'email', class => 'au', required => 1},
-    {name => 'passwd', class => 'au', required => 1},
-    {name => 'day_phone', class => 'au', required => 0},
-    {name => 'dob', class => 'au', required => 1},
-    {name => 'home_ou', class => 'au', required => 1},
-    {name => 'ident_type', class => 'au', required => 1},
-    {name => 'ident_value', class => 'au', required => 1},
-    {name => 'guardian',
-     class => 'au', 
-     notes => "AKA parent/guardian",
-     required_if => 'Patron is less than 18 years old'
-    },
-    {name => 'pref_first_given_name', class => 'au'},
-    {name => 'pref_second_given_name', class => 'au'},
-    {name => 'pref_family_name', class => 'au'},
-    {name => 'pref_suffix', class => 'au'},
-    {name => 'physical_street1', class => 'aua', required => 1},
-    {name => 'physical_street1_name'},
-    {name => 'physical_street2', class => 'aua'},
-    {name => 'physical_city', class => 'aua', required => 1},
-    {name => 'physical_post_code', class => 'aua', required => 1},
-    {name => 'physical_county', class => 'aua', required => 1},
-    {name => 'physical_state', class => 'aua', required => 1},
-    {name => 'physical_country', class => 'aua', required => 1},
-    {name => 'mailing_street1', class => 'aua', required => 1},
-    {name => 'mailing_street1_name'},
-    {name => 'mailing_street2', class => 'aua'},
-    {name => 'mailing_city', class => 'aua', required => 1},
-    {name => 'mailing_post_code', class => 'aua', required => 1},
-    {name => 'mailing_county', class => 'aua', required => 1},
-    {name => 'mailing_state', class => 'aua', required => 1},
-    {name => 'mailing_country', class => 'aua', required => 1},
-    {name => 'voter_registration', class => 'asvr', required => 0},
-    {name => 'in_house_registration', required => 0},
-);
-
+# Check URL to see if this is a new registration or a renewal
+# Do the subroutines have access to this variable???
+my $self = shift;
+my $path = $self->apache->path_info;
+
+if ($path =~ m|opac/erenew/submit|) {
+    my $update_type = 'renew';
+} else {
+    my $update_type = 'register';
+}
 
+# Create different api_fields array if registration or renewal
+if ($update_type == 'renew') {
+    my @api_fields = (
+        {name => 'vendor_username', required => 1},
+        {name => 'vendor_password', required => 1},
+        {name => 'patron_id', required => 1}, #needed for matching
+        {name => 'email', class => 'au', required => 1},
+        {name => 'day_phone', class => 'au', required => 1},
+        {name => 'home_ou', class => 'au', required => 1},
+        {name => 'pref_first_given_name', class => 'au'},
+        {name => 'pref_second_given_name', class => 'au'},
+        {name => 'pref_family_name', class => 'au'},
+        {name => 'physical_street1', class => 'aua', required => 1},
+        {name => 'physical_street1_name'},
+        {name => 'physical_street2', class => 'aua'},
+        {name => 'physical_city', class => 'aua', required => 1},
+        {name => 'physical_post_code', class => 'aua', required => 1},
+        {name => 'physical_county', class => 'aua', required => 1},
+        {name => 'physical_state', class => 'aua', required => 1},
+        {name => 'physical_country', class => 'aua', required => 1},
+        {name => 'mailing_street1', class => 'aua', required => 1},
+        {name => 'mailing_street1_name'},
+        {name => 'mailing_street2', class => 'aua'},
+        {name => 'mailing_city', class => 'aua', required => 1},
+        {name => 'mailing_post_code', class => 'aua', required => 1},
+        {name => 'mailing_county', class => 'aua', required => 1},
+        {name => 'mailing_state', class => 'aua', required => 1},
+        {name => 'mailing_country', class => 'aua', required => 1},
+        {name => 'voter_registration', class => 'asvr', required => 1},
+        {name => 'temp_renewal'} #new boolean value
+    );
+} else {
+    my @api_fields = (
+        {name => 'vendor_username', required => 1},
+        {name => 'vendor_password', required => 1},
+        {name => 'first_given_name', class => 'au', required => 1},
+        {name => 'second_given_name', class => 'au'},
+        {name => 'family_name', class => 'au', required => 1},
+        {name => 'suffix', class => 'au'},
+        {name => 'email', class => 'au', required => 1},
+        {name => 'passwd', class => 'au', required => 1},
+        {name => 'day_phone', class => 'au', required => 0},
+        {name => 'dob', class => 'au', required => 1},
+        {name => 'home_ou', class => 'au', required => 1},
+        {name => 'ident_type', class => 'au', required => 1},
+        {name => 'ident_value', class => 'au', required => 1},
+        {name => 'guardian',
+             class => 'au',
+             notes => "AKA parent/guardian",
+             required_if => 'Patron is less than 18 years old'
+        },
+        {name => 'pref_first_given_name', class => 'au'},
+        {name => 'pref_second_given_name', class => 'au'},
+        {name => 'pref_family_name', class => 'au'},
+        {name => 'pref_suffix', class => 'au'},
+        {name => 'physical_street1', class => 'aua', required => 1},
+        {name => 'physical_street1_name'},
+        {name => 'physical_street2', class => 'aua'},
+        {name => 'physical_city', class => 'aua', required => 1},
+        {name => 'physical_post_code', class => 'aua', required => 1},
+        {name => 'physical_county', class => 'aua', required => 1},
+        {name => 'physical_state', class => 'aua', required => 1},
+        {name => 'physical_country', class => 'aua', required => 1},
+        {name => 'mailing_street1', class => 'aua', required => 1},
+        {name => 'mailing_street1_name'},
+        {name => 'mailing_street2', class => 'aua'},
+        {name => 'mailing_city', class => 'aua', required => 1},
+        {name => 'mailing_post_code', class => 'aua', required => 1},
+        {name => 'mailing_county', class => 'aua', required => 1},
+        {name => 'mailing_state', class => 'aua', required => 1},
+        {name => 'mailing_country', class => 'aua', required => 1},
+        {name => 'voter_registration', class => 'asvr', required => 0},
+        {name => 'in_house_registration', required => 0},
+    );
+}
 sub load_ecard_form {
     my $self = shift;
     my $ctx = $self->ctx;
@@ -157,7 +199,7 @@ sub load_ecard_form {
 #        $logger->error("ECARD update failed for $barcode: " . $e->die_event);
 #        return;
 #    }
-#    
+#
 #    $e->commit;
 #    $logger->info("ECARD: Update to full ecard succeeded for $barcode");
 #
@@ -167,7 +209,6 @@ sub load_ecard_form {
 #    return;
 #}
 
-
 sub log_params {
     my $self = shift;
     my $cgi = $self->cgi;
@@ -176,11 +217,16 @@ sub log_params {
     my $msg = '';
     for my $p (@params) {
         next if $p =~ /pass/;
-        $msg .= "|" if $msg; 
+        $msg .= "|" if $msg;
         $msg .= "$p=".$cgi->param($p);
     }
 
-    $logger->info("ECARD: Submit params: $msg");
+    # use different log msg if reg or renew
+    if ($update_type == 'register') {
+        $logger->info("ECARD: Submit params: $msg");
+    } else {
+        $logger->info("E-RENEW: Submit params: $msg");
+    }
 }
 
 sub handle_testmode_api {
@@ -192,7 +238,7 @@ sub handle_testmode_api {
     for my $field_info (@api_fields) {
         my $doc_info = {};
         for my $info_key (keys %$field_info) {
-            $doc_info->{$info_key} = $field_info->{$info_key} 
+            $doc_info->{$info_key} = $field_info->{$info_key}
                 unless $info_key eq 'class';
         }
         push(@doc_fields, $doc_info);
@@ -211,8 +257,8 @@ sub handle_datamode_api {
     if ($datamode =~ /org_units/) {
         my $orgs = new_editor()->search_actor_org_unit({opac_visible => 't'});
         my $list = [
-            map { 
-                {name => $_->name, id => $_->id, parent_ou => $_->parent_ou} 
+            map {
+                {name => $_->name, id => $_->id, parent_ou => $_->parent_ou}
             } @$orgs
         ];
         $ctx->{response}->{messages} = [org_units => $list];
@@ -240,7 +286,7 @@ sub load_ecard_submit {
         return $self->compile_response;
     }
 
-    return Apache2::Const::FORBIDDEN unless 
+    return Apache2::Const::FORBIDDEN unless
         $cgi->request_method eq 'POST' &&
         $self->verify_vendor_host &&
         $self->login_vendor;
@@ -254,24 +300,33 @@ sub load_ecard_submit {
     return $self->handle_testmode_api if $testmode eq 'API';
     return $self->handle_datamode_api($datamode) if $datamode;
 
-    return $self->compile_response unless $self->make_user;
-    return $self->compile_response unless $self->add_addresses;
-    return $self->compile_response unless $self->check_dupes;
-    return $self->compile_response unless $self->add_card;
-    # Add survey responses commented out because it is not universal.
-    # We should come up with a way to configure it before uncommenting
-    # it globally.
-    #return $self->compile_response unless $self->add_survey_responses;
-    return $self->compile_response unless $self->save_user;
-    return $self->compile_response unless $self->add_usr_settings;
-    return $self->compile_response if $ctx->{response}->{status};
-
-    # The code below does nothing in a stock Evergreen installation.
-    # It is included in case a site wishes to set up action trigger
-    # events to do some additional verification or notification for
-    # patrons who have signed up for an eCard.
-    $U->create_events_for_hook(
-        'au.create.ecard', $ctx->{user}, $ctx->{user}->home_ou);
+    # Accommodate reg vs renew
+    if ($update_type == 'register') {
+        return $self->compile_response unless $self->make_user;
+        return $self->compile_response unless $self->add_addresses;
+        return $self->compile_response unless $self->check_dupes;
+        return $self->compile_response unless $self->add_card;
+        # Add survey responses commented out because it is not universal.
+        # We should come up with a way to configure it before uncommenting
+        # it globally.
+        #return $self->compile_response unless $self->add_survey_responses;
+        return $self->compile_response unless $self->save_user;
+        return $self->compile_response unless $self->add_usr_settings;
+        return $self->compile_response if $ctx->{response}->{status};
+
+        # The code below does nothing in a stock Evergreen installation.
+        # It is included in case a site wishes to set up action trigger
+        # events to do some additional verification or notification for
+        # patrons who have signed up for an eCard.
+        $U->create_events_for_hook(
+            'au.create.ecard', $ctx->{user}, $ctx->{user}->home_ou);
+    } else {
+        return $self->compile_response unless $self->update_user;
+        return $self->compile_response unless $self->update_addresses;
+        return $self->compile_response unless $self->add_survey_responses;
+        return $self->compile_response unless $self->save_user;
+        return $self->compile_response if $ctx->{response}->{status};
+    }
 
     $ctx->{response}->{status} = 'OK';
     $ctx->{response}->{barcode} = $ctx->{user}->card->barcode;
@@ -280,7 +335,7 @@ sub load_ecard_submit {
     return $self->compile_response;
 }
 
-# E-card vendor is not a regular account.  They must have an entry in 
+# E-card vendor is not a regular account.  They must have an entry in
 # the password table with password type ecard_vendor.
 sub login_vendor {
     my $self = shift;
@@ -327,16 +382,23 @@ sub verify_vendor_host {
     return 1;
 }
 
-
 sub compile_response {
     my $self = shift;
     my $ctx = $self->ctx;
     $self->apache->content_type("application/json; charset=utf-8");
     $ctx->{response} = OpenSRF::Utils::JSON->perl2JSON($ctx->{response});
-    $logger->info("ECARD responding with " . $ctx->{response});
+    # Different log message if renew
+    if ($update_type == 'register') {
+        $logger->info("ECARD responding with " . $ctx->{response});
+    } else {
+        $logger->info("E-RENEW responding with " . $ctx->{response});
+    }
     return Apache2::Const::OK;
 }
 
+#Do we need to change this line if usrname and passwd do not exist in
+#renewal api object?
+#Do we even need to do this at all? I don't see that we're calling it
 my %keep_case = (usrname => 1, passwd => 1, email => 1);
 sub upperclense {
     my $self = shift;
@@ -393,10 +455,65 @@ sub make_user {
         $au->$field($val);
     }
 
-    return undef if $ctx->{response}->{status}; 
+    return undef if $ctx->{response}->{status};
+    return $ctx->{user} = $au;
+}
+
+# New sub to update a user
+sub update_user {
+    my $self = shift;
+    my $ctx = $self->ctx;
+    my $cgi = $self->cgi;
+
+    my $au = Fieldmapper::actor::user->new;
+
+    # Grab user id - is this how we match the right patron to update?
+    $au->id($cgi->param('patron_id'));
+
+    # We need to figure out how to append this value rather than replace
+    $au->name_keywords('quipu_renew');
+
+    my $home_ou = $cgi->param('home_ou');
+
+    # Temp renewal is only 30 days, otherwise use perm_interval
+    # Is using '30 days' the right syntax here?
+    my $temp_renewal = $cgi->param('temp_renewal');
+
+    if ($temp_renewal == '1') {
+        $au->expire_date(
+            DateTime(now(time_zone => 'local')->add(
+                seconds => interval_to_seconds('30 days')->iso8601()
+    } else {
+        $au->profile($perm_grp);
+        my $grp = new_editor()->retrieve_permission_grp_tree($perm_grp);
+        $au->expire_date(
+            DateTime->now(time_zone => 'local')->add(
+                seconds => interval_to_seconds($grp->perm_interval))->iso8601()
+        );
+    }
+
+    # loop through fields submitted by quipu
+    for my $field_info (@api_fields) {
+        my $field = $field_info->{name};
+        next unless $field_info->{class} eq 'au';
+
+        my $val = $cgi->param($field);
+
+        if ($field_info->{required} && !$val) {
+            my $msg = "Value required for field: '$field'";
+            $ctx->{response}->{status} = 'INVALID_PARAMS';
+            push(@{$ctx->{response}->{messages}}, $msg);
+            $logger->error("E-RENEW $msg");
+        }
+
+        $val = undef if $field eq 'day_phone' && $val eq '--';
+        $au->$field($val);
+    }
+
     return $ctx->{user} = $au;
 }
 
+# Card generation must occur after the user is saved in the DB.
 sub add_card {
     my $self = shift;
     my $ctx = $self->ctx;
@@ -556,7 +673,74 @@ sub add_addresses {
     }
 
     # exit if there were any errors above.
-    return undef if $ctx->{response}->{status}; 
+    return undef if $ctx->{response}->{status};
+
+    $user->billing_address($physical_addr);
+    $user->mailing_address($mailing_addr);
+    $user->addresses([$physical_addr, $mailing_addr]);
+
+    return 1;
+}
+
+
+# New subroutine to update existing addresses
+# Need to figure out how to update the right ones
+sub update_addresses {
+    my $self = shift;
+    my $cgi = $self->cgi;
+    my $ctx = $self->ctx;
+    my $e = $ctx->{editor};
+    my $user = $ctx->{user}; # probably need to do something else here?
+
+    # Need to see how to pass the patron id properly here
+    # Do we need to get the ID of the existing address?
+    # Or will it match because of the address_type?
+    my $physical_addr = Fieldmapper::actor::user_address->new;
+    $physical_addr->isnew(0); # is this right?
+    $physical_addr->usr($user->id);
+    $physical_addr->address_type('PHYSICAL');
+    $physical_addr->within_city_limits('f');
+
+    my $mailing_addr = Fieldmapper::actor::user_address->new;
+    $mailing_addr->isnew(0); # is this right?
+    $mailing_addr->usr($user->id);
+    $mailing_addr->address_type('MAILING');
+    $mailing_addr->within_city_limits('f');
+
+   # Use as both billing and mailing via virtual ID.
+    $physical_addr->id(-1);
+    $mailing_addr->id(-2);
+    $user->billing_address(-1);
+    $user->mailing_address(-2);
+
+    # Confirm we have values for all of the required fields.
+    # Apply values to our in-progress address object.
+    for my $field_info (@api_fields) {
+        my $field = $field_info->{name};
+        next unless $field =~ /physical|mailing/;
+        next if $field =~ /street1_/;
+
+        my $val = $cgi->param($field);
+
+        if ($field_info->{required} && !$val) {
+            my $msg = "Value required for field: '$field'";
+            $ctx->{response}->{status} = 'INVALID_PARAMS';
+            push(@{$ctx->{response}->{messages}}, $msg);
+            $logger->error("E-RENEW $msg");
+        }
+
+        if ($field =~ /physical/) {
+            (my $col_field = $field) =~ s/physical_//g;
+            $physical_addr->$col_field($val) if $val;
+        } else {
+            (my $col_field = $field) =~ s/mailing_//g;
+            $mailing_addr->$col_field($val) if $val;
+        }
+
+    }
+
+    # exit if there were any errors above.
+    return undef if $ctx->{response}->{status};
 
     $user->billing_address($physical_addr);
     $user->mailing_address($mailing_addr);
@@ -605,35 +789,6 @@ sub add_survey_responses {
     return 1;
 }
 
-# TODO: this is KCLS-specific, but maybe we can make it something
-# generic for adding stat cats to the patron
-
-#sub add_stat_cats {
-#    my $self = shift;
-#    my $cgi = $self->cgi;
-#    my $user = $self->ctx->{user};
-#
-#    my $ds_map = Fieldmapper::actor::stat_cat_entry_user_map->new;
-#    $ds_map->isnew(1);
-#    $ds_map->stat_cat(12);
-#    $ds_map->stat_cat_entry('KCLS');
-#
-#    my $events = $cgi->param('events_mailing');
-#    my $em_map = Fieldmapper::actor::stat_cat_entry_user_map->new;
-#    $em_map->isnew(1);
-#    $em_map->stat_cat(3);
-#    $em_map->stat_cat_entry($events ? 'Y' : 'N');
-#
-#    my $foundation = $cgi->param('foundation_mailing');
-#    my $fm_map = Fieldmapper::actor::stat_cat_entry_user_map->new;
-#    $fm_map->isnew(1);
-#    $fm_map->stat_cat(4);
-#    $fm_map->stat_cat_entry($foundation ? 'Y' : 'N');
-#
-#    $user->stat_cat_entries([$ds_map, $em_map, $fm_map]);
-#    return 1;
-#}
-
 # Returns true if no dupes found, false if dupes are found.
 sub check_dupes {
     my $self = shift;
@@ -645,7 +800,7 @@ sub check_dupes {
     #TODO: This list of fields should be configurable so that code
     #changes are not required for different sites with different
     #criteria.
-    my @dupe_patron_fields = 
+    my @dupe_patron_fields =
         qw/first_given_name family_name dob/;
 
     my $search = {
@@ -657,7 +812,7 @@ sub check_dupes {
     my $root_org = $e->search_actor_org_unit({parent_ou => undef})->[0];
 
     my $ids = $U->storagereq(
-        "open-ils.storage.actor.user.crazy_search", 
+        "open-ils.storage.actor.user.crazy_search",
         $search,
         1000,           # search limit
         undef,          # sort
@@ -706,8 +861,8 @@ sub check_dupes {
     return 1 if @$ids == 0;
 
     $ctx->{response}->{status} = 'DUPLICATE';
-    $ctx->{response}->{messages} = ['first_given_name', 
-        'family_name', 'dob_year', 'billing_street1_name'];
+    $ctx->{response}->{messages} = ['first_given_name',
+                                    'family_name', 'dob_year', 'billing_street1_name'];
     return undef;
 }
 
@@ -716,7 +871,7 @@ sub save_user {
     my $self = shift;
     my $ctx = $self->ctx;
     my $cgi = $self->cgi;
-    my $user = $ctx->{user};
+    my $user = $ctx->{user}; #Do we need to change this for renew?
 
     my $resp = $U->simplereq(
         'open-ils.actor',
@@ -728,10 +883,16 @@ sub save_user {
 
     if ($U->is_event($resp)) {
 
+    if ($update_type == 'register') {
         my $msg = "Error creating user account: " . $resp->{textcode};
         $logger->error("ECARD: $msg");
-
         $ctx->{response}->{status} = 'CREATE_ERR';
+    } else {
+        my $msg = "Error updating user account: " . $resp->{textcode};
+        $logger->error("E-RENEW: $msg");
+        $ctx->{response}->{status} = 'UPDATE_ERR'; # Does this work?
+    }
+
         $ctx->{response}->{messages} = [{msg => $msg, pid => $$}];
 
         return 0;
@@ -742,4 +903,3 @@ sub save_user {
 }
 
 1;
-