Lp 1902937: Make the Quipu Integration Code More Generic
authorJason Stephenson <jason@sigio.com>
Fri, 10 Sep 2021 16:56:16 +0000 (12:56 -0400)
committerJason Stephenson <jstephenson@cwmars.org>
Tue, 29 Nov 2022 15:31:54 +0000 (10:31 -0500)
Rename quipu upgrade script.

Enable ecard form in EGCatLoader.

Add the calculate_luhn_checkdigit function to calculate a barcode
check digit using the Luhn algorithm to OpenILS::Applicaiton::AppUtils
because it could be useful for more than just generating barcodes for
the eCard integration.  We may also need more than one check digit
algorithm in the future.

Replace the KCLS specific registration form with one that is more generic.

Add new settings.

Add the generate_barcode utility function.

Modify Ecard login_vendor to use org unit settings

Change the login field value to FALSE so it can't be used to login.

Add evergreen.upgrade_deps_block_check to upgrade script

Add Ecard registration link to OPAC footer

Make voter registration field optional in Ecard.pm because not
everyone has or requires this survey.  It is PINES-specific.

Do not set actor.usr.name_keywords in Ecard.pm

Make day_phone optional.

Make in_house_registration optional.

Return the user's expiration date, in ISO format (YYYY-MM-DD), as the
"expiration_date" field in a successful response to Quipu.

Signed-off-by: Jason Stephenson <jason@sigio.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Ecard.pm
Open-ILS/src/sql/Pg/005.schema.actors.sql
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/XXXX-quipu-ecard-integration.sql [deleted file]
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.quipu-ecard-integration.sql [new file with mode: 0644]
Open-ILS/src/templates/opac/ecard/form.tt2
Open-ILS/src/templates/opac/parts/footer.tt2

index 3c32377..899c5a8 100644 (file)
@@ -2515,6 +2515,79 @@ sub verify_migrated_user_password {
         $e, $user_id, md5_hex($salt . $md5_pass), $pw_type);
 }
 
+# Calculate a barcode check digit using the Luhn algorithm:
+# https://en.wikipedia.org/wiki/Luhn_algorithm
+# Takes a string of digits and returns the checkdigit.
+# -1 is returned if the string contains any characters other than digits.
+sub calculate_luhn_checkdigit {
+    my ($class, $input) = @_;
+    return -1 unless ($input =~ /^\d+$/);
+    my @bc = reverse(split(//, $input));
+    my $mult = 2;
+    my $sum = 0;
+    for (my $i = 0; $i < @bc; $i++) {
+        my $v = $bc[$i] * $mult;
+        $v -= 9 if ($v > 9);
+        $sum += $v;
+        $mult = ($mult == 2) ? 1 : 2;
+    }
+    return ($sum % 10) ? 10 - ($sum % 10) : 0;
+}
+
+# Generate a barcode using a combination of:
+# $prefix : A prefix sequence for the barcode.
+# $length : The total lenght for the generated barcode, including
+#           length of the prefix and checkdigit (if any).
+# $checkdigit: A boolean, whether or not to calculate a check digit.
+# $sequence: A database sequence to use as a source of the main digit
+#            sequence for the barcode.
+# $e : An optional CStoreEditor to use for queries.  If not provided,
+#      a new one will be created and used.
+#
+# Returns the new barcode or undef on failure.
+sub generate_barcode {
+    my ($class, $prefix, $length, $checkdigit, $sequence, $e) = @_;
+    $e = OpenILS::Utils::CStoreEditor->new() unless($e);
+    # Don't do checkdigit if prefix is not all numbers.
+    if ($prefix !~ /^\d+$/) {
+        $checkdigit = 0;
+    }
+    $length = $length - length($prefix);
+    $length -= 1 if ($checkdigit);
+    if ($length > 0) {
+        my $barcode;
+        do {
+            my $r = $e->json_query(
+                {from => [
+                    'actor.generate_barcode',
+                    $prefix,
+                    $length,
+                    $sequence
+                ]});
+            if ($r && $r->[0] && $r->[0]->{'actor.generate_barcode'}) {
+                $barcode = $r->[0]->{'actor.generate_barcode'};
+                if ($checkdigit) {
+                    $barcode .= $class->calculate_luhn_checkdigit($barcode);
+                }
+                # Check for duplication.
+                my $x = $e->json_query(
+                    {
+                        select => ['id'],
+                        from => 'ac',
+                        where => {
+                            barcode => $barcode
+                        }
+                    }
+                );
+                undef($barcode) if ($x && $x->[0]);
+            } else {
+                return undef;
+            }
+        } until ($barcode);
+        return $barcode;
+    }
+    return undef;
+}
 
 # generate a MARC XML document from a MARC XML string
 sub marc_xml_to_doc {
index eecbf71..11eff6a 100644 (file)
@@ -186,8 +186,7 @@ sub load {
 
     $self->load_simple("myopac") if $path =~ m:opac/myopac:; # A default page for myopac parts
 
-    # maybe make these optional parts of load_patron_reg?
-    #return $self->load_ecard_form if $path =~ m|opac/ecard/form|;
+    return $self->load_ecard_form if $path =~ m|opac/ecard/form|;
     return $self->load_ecard_submit if $path =~ m|opac/ecard/submit|;
     return $self->load_ecard_verify if $path =~ m|opac/ecard/verify|;
 
index e3fb930..68481c8 100644 (file)
@@ -24,7 +24,7 @@ my @api_fields = (
     {name => 'suffix', class => 'au'},
     {name => 'email', class => 'au', required => 1},
     {name => 'passwd', class => 'au', required => 1},
-    {name => 'day_phone', 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},
@@ -54,11 +54,28 @@ my @api_fields = (
     {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 => 'in_house_registration', 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;
+    my $cgi = $self->cgi;
+
+    my $ctx_org = $ctx->{physical_loc} || $self->_get_search_lib();
+    $ctx->{ecard} = {};
+    $ctx->{ecard}->{enabled} = $U->is_true($U->ou_ancestor_setting_value(
+        $ctx_org, 'opac.ecard_registration_enabled'
+    ));
+    $ctx->{ecard}->{quipu_id} = $U->ou_ancestor_setting_value(
+        $ctx_org, 'lib.ecard_quipu_id'
+    ) || 0;
+
+    return Apache2::Const::OK;
+}
+
 # TODO: wrap the following in a check for a library setting as to whether or not
 # to require emailed verification
 
@@ -241,16 +258,24 @@ sub load_ecard_submit {
     return $self->compile_response unless $self->add_addresses;
     return $self->compile_response unless $self->check_dupes;
     return $self->compile_response unless $self->add_card;
-    return $self->compile_response unless $self->add_survey_responses;
+    # 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);
 
     $ctx->{response}->{status} = 'OK';
     $ctx->{response}->{barcode} = $ctx->{user}->card->barcode;
+    $ctx->{response}->{expiration_date} = substr($ctx->{user}->expire_date, 0, 10);
 
     return $self->compile_response;
 }
@@ -261,6 +286,7 @@ sub login_vendor {
     my $self = shift;
     my $username = $self->cgi->param('vendor_username');
     my $password = $self->cgi->param('vendor_password');
+    my $home_ou = $self->cgi->param('home_ou');
 
     my $e = new_editor();
     my $vendor = $e->search_actor_user({usrname => $username})->[0];
@@ -270,11 +296,20 @@ sub login_vendor {
         $e, $vendor->id, $password, 'ecard_vendor');
 
     # Auth checks out OK.  Manually create an authtoken
-
+    my %admin_settings = $U->ou_ancestor_setting_batch_insecure(
+        $home_ou,
+        [
+            'lib.ecard_admin_usrname',
+            'lib.ecard_admin_org_unit'
+        ]
+    );
+    my $admin_usr = $e->search_actor_user({usrname => $admin_settings{'lib.ecard_admin_usrname'}->{'value'}})->[0]
+        || $vendor;
+    my $admin_org = $admin_settings{'lib.ecard_admin_org_unit'}->{'value'} || 1;
     my $auth = $U->simplereq(
         'open-ils.auth_internal',
         'open-ils.auth_internal.session.create',
-        {user_id => 1, org_unit => 394, login_type => 'temp'}
+        {user_id => $admin_usr->id(), org_unit => $admin_org, login_type => 'temp'}
     );
 
     return unless $auth && $auth->{textcode} eq 'SUCCESS';
@@ -320,11 +355,9 @@ sub make_user {
     my $cgi = $self->cgi;
 
     my $au = Fieldmapper::actor::user->new;
-    my $in_house = $cgi->param('in_house_registration');
 
     $au->isnew(1);
     $au->net_access_level(1); # Filtered
-    $au->name_keywords($in_house ? 'quipu_inhouse' : 'quipu_remote');
     my $home_ou = $cgi->param('home_ou');
 
     my $perm_grp = $U->ou_ancestor_setting_value(
@@ -360,31 +393,38 @@ sub make_user {
         $au->$field($val);
     }
 
-    # Usename defaults to the user barcode
     return undef if $ctx->{response}->{status}; 
     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;
     my $cgi = $self->cgi;
     my $user = $ctx->{user};
     my $home_ou = $cgi->param('home_ou');
-    my $prefix = $U->ou_ancestor_setting_value(
-        $home_ou, 
-        'lib.ecard_barcode_prefix'
-    ) || 'AUTO';
-
-    my $bc = new_editor()->json_query({from => [
-        'actor.generate_barcode', 
-        $prefix, # ecard prefix
-        8, # length of autogenated portion
-        'actor.auto_barcode_ecard_seq' # base sequence for autogeneration.
-    ]})->[0];
 
-    my $barcode = $bc->{'actor.generate_barcode'};
+    my %settings = $U->ou_ancestor_setting_batch_insecure(
+        $home_ou,
+        [
+            'lib.ecard_barcode_prefix',
+            'lib.ecard_barcode_length',
+            'lib.ecard_barcode_calculate_checkdigit'
+        ]
+    );
+    my $prefix = $settings{'lib.ecard_barcode_prefix'}->{'value'}
+        || 'AUTO';
+    my $length = $settings{'lib.card_barcode_length'}->{'value'}
+        || 14;
+    my $cd = $settings{'lib.ecard_barcode_calculate_checkdigit'}->{'value'}
+        || 0;
+
+    my $barcode = $U->generate_barcode(
+        $prefix,
+        $length,
+        $U->is_true($cd),
+        'actor.auto_barcode_ecard_seq'
+    );
 
     $logger->info("ECARD using generated barcode: $barcode");
 
@@ -517,6 +557,8 @@ sub add_addresses {
     return 1;
 }
 
+# TODO: The code in add_usr_settings is totally arbitrary and should
+# be modified to look up settings in the database.
 sub add_usr_settings {
     my $self = shift;
     my $cgi = $self->cgi;
@@ -534,6 +576,10 @@ sub add_usr_settings {
     return 1;
 }
 
+# TODO: This implementation of add_survey_responses is PINES-specific.
+# KCLS does something else.  The line that calls this subroutine is
+# commented out above.  This should be modified to look up settings in
+# the database.
 sub add_survey_responses {
     my $self = shift;
     my $cgi = $self->cgi;
@@ -588,6 +634,9 @@ sub check_dupes {
     my $addr = $user->addresses->[0];
     my $e = new_editor();
 
+    #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 = 
         qw/first_given_name family_name dob/;
 
index 14ce1d0..4de8937 100644 (file)
@@ -215,13 +215,6 @@ CREATE SEQUENCE actor.auto_barcode_ecard_seq START 100 MAXVALUE 9999999;
 CREATE OR REPLACE FUNCTION actor.generate_barcode
     (prefix TEXT, numchars INTEGER, seqname TEXT) RETURNS TEXT AS
 $$
-/*
-Generate a barcode starting with 'prefix' and followed by 'numchars'
-numbers.  The auto portion numbers are generated from the provided
-sequence, guaranteeing uniquness across all barcodes generated with
-the same sequence.  The number is left-padded with zeros to meet the
-numchars size requirement.  Returns NULL if the sequnce value is
-higher than numchars can accommodate .*/
        SELECT NEXTVAL($3); -- bump the sequence up 1
        SELECT CASE
                WHEN LENGTH(CURRVAL($3)::TEXT) > $2 THEN NULL
@@ -229,6 +222,15 @@ higher than numchars can accommodate .*/
                END;
 $$ LANGUAGE SQL;
 
+COMMENT ON FUNCTION actor.generate_barcode(TEXT, INTEGER, TEXT) IS $$
+Generate a barcode starting with 'prefix' and followed by 'numchars'
+numbers.  The auto portion numbers are generated from the provided
+sequence, guaranteeing uniquness across all barcodes generated with
+the same sequence.  The number is left-padded with zeros to meet the
+numchars size requirement.  Returns NULL if the sequnce value is
+higher than numchars can accommodate.
+$$;
+
 CREATE TABLE actor.stat_cat_sip_fields (
     field   CHAR(2) PRIMARY KEY,
     name    TEXT    NOT NULL,
index b478fb5..4256f31 100644 (file)
@@ -4561,6 +4561,22 @@ INSERT into config.org_unit_setting_type
         'coust', 'description'),
     'string', null)
 
+,( 'opac.ecard_registration_enabled', 'opac',
+    oils_i18n_gettext('opac.ecard_registration_enabled',
+        'Enable eCard registration feature in the OPAC',
+        'coust', 'label'),
+    oils_i18n_gettext('opac.ecard_registration_enabled',
+        'Enable access to the eCard registration form in the OPAC',
+        'coust', 'description'),
+    'bool', null)
+,( 'lib.ecard_quipu_id', 'lib',
+    oils_i18n_gettext('lib.ecard_quipu_id',
+        'Quipu eCard Customer Account',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_quipu_id',
+        'Quipu Customer Account ID to be used for eCard registration',
+        'coust', 'description'),
+    'integer', null)
 ,( 'lib.ecard_barcode_prefix', 'lib',
     oils_i18n_gettext('lib.ecard_barcode_prefix',
         'Barcode prefix for Quipu eCard feature',
@@ -4569,15 +4585,46 @@ INSERT into config.org_unit_setting_type
         'Set the barcode prefix for new Quipu eCard users',
         'coust', 'description'),
     'string', null)
-
+,( 'lib.ecard_barcode_length', 'lib',
+    oils_i18n_gettext('lib.ecard_barcode_length',
+        'Barcode length for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_barcode_length',
+        'Set the barcode length for new Quipu eCard users',
+        'coust', 'description'),
+    'integer', null)
+,( 'lib.ecard_barcode_calculate_checkdigit', 'lib',
+    oils_i18n_gettext('lib.ecard_barcode_calculate_checkdigit',
+        'Calculate barcode checkdigit for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_barcode_calculate_checkdigit',
+        'Calculate the barcode check digit for new Quipu eCard users',
+        'coust', 'description'),
+    'bool', null)
 ,( 'lib.ecard_patron_profile', 'lib',
     oils_i18n_gettext('lib.ecard_patron_profile',
         'Patron permission profile for Quipu eCard feature',
         'coust', 'label'),
-    oils_i18n_gettext('lib.ecard_barcode_prefix',
+    oils_i18n_gettext('lib.ecard_patron_profile',
         'Patron permission profile for Quipu eCard feature',
         'coust', 'description'),
     'link', 'pgt')
+,( 'lib.ecard_admin_usrname', 'lib',
+    oils_i18n_gettext('lib.ecard_admin_usrname',
+        'Evergreen Admin Username for the Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_admin_usrname',
+        'Username of the Evergreen admin account that will create new Quipu eCard users',
+        'coust', 'description'),
+    'string', null)
+,( 'lib.ecard_admin_org_unit', 'lib',
+    oils_i18n_gettext('lib.ecard_admin_org_unit',
+        'Admin organizational unit for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_admin_org_unit',
+        'Organizational unit used by the Evergreen admin user of the Quipu eCard feature',
+        'coust', 'description'),
+    'link', 'aou')
 
 ,( 'lib.info_url', 'lib',
     oils_i18n_gettext('lib.info_url',
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX-quipu-ecard-integration.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX-quipu-ecard-integration.sql
deleted file mode 100644 (file)
index 378856c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-BEGIN;
-
--- Thank you, berick :-)
--- Start at 100 to avoid barcodes with long stretches of zeros early on.
--- eCard barcodes have 7 auto-generated digits.
-CREATE SEQUENCE actor.auto_barcode_ecard_seq START 100 MAXVALUE 9999999;
-                                                                               
-CREATE OR REPLACE FUNCTION actor.generate_barcode
-    (prefix TEXT, numchars INTEGER, seqname TEXT) RETURNS TEXT AS
-$$
-/*
-Generate a barcode starting with 'prefix' and followed by 'numchars'
-numbers.  The auto portion numbers are generated from the provided
-sequence, guaranteeing uniquness across all barcodes generated with
-the same sequence.  The number is left-padded with zeros to meet the
-numchars size requirement.  Returns NULL if the sequnce value is
-higher than numchars can accommodate .*/
-    SELECT NEXTVAL($3); -- bump the sequence up 1
-    SELECT CASE
-        WHEN LENGTH(CURRVAL($3)::TEXT) > $2 THEN NULL
-        ELSE $1 || LPAD(CURRVAL($3)::TEXT, $2, '0')
-    END;
-$$ LANGUAGE SQL;
-
-INSERT INTO actor.passwd_type
-    (code, name, login, crypt_algo, iter_count)
-    VALUES ('ecard_vendor', 'eCard Vendor Password', TRUE, 'bf', 10);
-
-INSERT into config.org_unit_setting_type
-( name, grp, label, description, datatype, fm_class ) VALUES
-
-( 'lib.ecard_barcode_prefix', 'lib',
-    oils_i18n_gettext('lib.ecard_barcode_prefix',
-        'Barcode prefix for Quipu eCard feature',
-        'coust', 'label'),
-    oils_i18n_gettext('lib.ecard_barcode_prefix',
-        'Set the barcode prefix for new Quipu eCard users',
-        'coust', 'description'),
-    'string', null)
-
-,( 'lib.ecard_patron_profile', 'lib',
-    oils_i18n_gettext('lib.ecard_patron_profile',
-        'Patron permission profile for Quipu eCard feature',
-        'coust', 'label'),
-    oils_i18n_gettext('lib.ecard_barcode_prefix',
-        'Patron permission profile for Quipu eCard feature',
-        'coust', 'description'),
-    'link', 'pgt')
-;
-
-COMMIT;
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.quipu-ecard-integration.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.quipu-ecard-integration.sql
new file mode 100644 (file)
index 0000000..709eac6
--- /dev/null
@@ -0,0 +1,102 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); -- berick/csharp/Dyrcona
+
+-- Thank you, berick :-)
+-- Start at 100 to avoid barcodes with long stretches of zeros early on.
+-- eCard barcodes have 7 auto-generated digits.
+CREATE SEQUENCE actor.auto_barcode_ecard_seq START 100 MAXVALUE 9999999;
+
+CREATE OR REPLACE FUNCTION actor.generate_barcode
+    (prefix TEXT, numchars INTEGER, seqname TEXT) RETURNS TEXT AS
+$$
+    SELECT NEXTVAL($3); -- bump the sequence up 1
+    SELECT CASE
+        WHEN LENGTH(CURRVAL($3)::TEXT) > $2 THEN NULL
+        ELSE $1 || LPAD(CURRVAL($3)::TEXT, $2, '0')
+    END;
+$$ LANGUAGE SQL;
+
+COMMENT ON FUNCTION actor.generate_barcode(TEXT, INTEGER, TEXT) IS $$
+Generate a barcode starting with 'prefix' and followed by 'numchars'
+numbers.  The auto portion numbers are generated from the provided
+sequence, guaranteeing uniquness across all barcodes generated with
+the same sequence.  The number is left-padded with zeros to meet the
+numchars size requirement.  Returns NULL if the sequnce value is
+higher than numchars can accommodate.
+$$;
+
+INSERT INTO actor.passwd_type
+    (code, name, login, crypt_algo, iter_count)
+    VALUES ('ecard_vendor', 'eCard Vendor Password', FALSE, 'bf', 10);
+
+INSERT INTO config.org_unit_setting_type
+( name, grp, label, description, datatype, fm_class )
+VALUES
+( 'opac.ecard_registration_enabled', 'opac',
+    oils_i18n_gettext('opac.ecard_registration_enabled',
+        'Enable eCard registration feature in the OPAC',
+        'coust', 'label'),
+    oils_i18n_gettext('opac.ecard_registration_enabled',
+        'Enable access to the eCard registration form in the OPAC',
+        'coust', 'description'),
+    'bool', null)
+,( 'lib.ecard_quipu_id', 'lib',
+    oils_i18n_gettext('lib.ecard_quipu_id',
+        'Quipu eCard Customer Account',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_quipu_id',
+        'Quipu Customer Account ID to be used for eCard registration',
+        'coust', 'description'),
+    'integer', null)
+,( 'lib.ecard_barcode_prefix', 'lib',
+    oils_i18n_gettext('lib.ecard_barcode_prefix',
+        'Barcode prefix for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_barcode_prefix',
+        'Set the barcode prefix for new Quipu eCard users',
+        'coust', 'description'),
+    'string', null)
+,( 'lib.ecard_barcode_length', 'lib',
+    oils_i18n_gettext('lib.ecard_barcode_length',
+        'Barcode length for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_barcode_length',
+        'Set the barcode length for new Quipu eCard users',
+        'coust', 'description'),
+    'integer', null)
+,( 'lib.ecard_barcode_calculate_checkdigit', 'lib',
+    oils_i18n_gettext('lib.ecard_barcode_calculate_checkdigit',
+        'Calculate barcode checkdigit for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_barcode_calculate_checkdigit',
+        'Calculate the barcode check digit for new Quipu eCard users',
+        'coust', 'description'),
+    'bool', null)
+,( 'lib.ecard_patron_profile', 'lib',
+    oils_i18n_gettext('lib.ecard_patron_profile',
+        'Patron permission profile for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_patron_profile',
+        'Patron permission profile for Quipu eCard feature',
+        'coust', 'description'),
+    'link', 'pgt')
+,( 'lib.ecard_admin_usrname', 'lib',
+    oils_i18n_gettext('lib.ecard_admin_usrname',
+        'Evergreen Admin Username for the Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_admin_usrname',
+        'Username of the Evergreen admin account that will create new Quipu eCard users',
+        'coust', 'description'),
+    'string', null)
+,( 'lib.ecard_admin_org_unit', 'lib',
+    oils_i18n_gettext('lib.ecard_admin_org_unit',
+        'Admin organizational unit for Quipu eCard feature',
+        'coust', 'label'),
+    oils_i18n_gettext('lib.ecard_admin_org_unit',
+        'Organizational unit used by the Evergreen admin user of the Quipu eCard feature',
+        'coust', 'description'),
+    'link', 'aou')
+;
+
+COMMIT;
index 909cb7a..4f29711 100644 (file)
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <title>[% l('Get an eCard') %]</title>
-    [% INCLUDE 'opac/parts/googalytics_new.tt2' %]
-    [% INCLUDE 'opac/parts/goog_tag_manager.tt2' %]
-
-    <!-- NOTE: BootstrapCSS v4 does not play nicely with BC headers -->
-    <link rel="stylesheet" href="/js/ui/default/staff/build/css/bootstrap.min.css" />
-
-    <!-- QUIPU CSS -->
-    <link rel="stylesheet" href="https://ecard.quipugroup.net/css/eCARD.css">
-    <link rel="stylesheet"
-      href="https://ecard.quipugroup.net/js/jqueryUI/css/ui-lightness/jquery-ui-1.10.4.custom.min.css">
-    <!-- END QUIPU CSS -->
-
-    <!-- local CSS -->
-    <style>
-      /* BC screen reader links are not correctly hidden via their API.
-         Add some additional CSS to hide them */
-      .screen_reader_nav {
-        position: absolute;
-        top: -1000px;
-        left: -1000px;
-        z-index: 0;
-      }
-      #ecard-container-wrapper {
-        width: 98%;
-      }
-      #ecard-container {
-        margin-bottom: 20px;
-        color: #585d5e;
-        font-family: 'Open Sans', sans-serif;
-        letter-spacing: .5pt;
-        font-size: 15px;
-        width: 900px; /* to match bibliocms */
-        margin-left: auto;
-        margin-right: auto;
-      }
-    </style>
-
-    <!-- BC CSS -->
-    [% ctx.bc_css %]
-    <!-- BC END CSS -->
-
-  </head>
-  <body>
-
-    [% INCLUDE 'opac/parts/goog_tag_manager_noscript.tt2' %]
-
-    <!-- BC SCREEN READER NAVIGATION -->
-    [% ctx.bc_screen_reader_navigation %]
-    <!-- BC END SCREEN READER NAVIGATION -->
-
-    <!-- BC HEADER -->
-    [% ctx.bc_header %]
-    <!-- BC END HEADER -->
-
-    <div id='ecard-container-wrapper'>
-      <div id='ecard-container'>
-
-        <div id='ecard-preamble'>
-
-          <h1>Get a KCLS eCard</h1>
-
-          <p>
-            Please fill out the application below to get immediate 24/7
-            access to King County Library System’s online services
-            including e-books and audiobooks, movies and music, online
-            classes, exam prep and research databases, and magazines.
-          </p>
-          <!--
-          <p>
-            Please apply <a title="Get A Library Card"
-              href="https://w3.kcls.org/get-a-library-card">here</a>
-            if you would prefer a card with full library privileges 
-            including check out, computer use and printing.
-          </p>
-          -->
-          <p>
-            If your eCard application is successful we will mail
-            a confirmation letter to you in order to verify your
-            address. You must follow the instructions in the letter so
-            that the account remains open.
-          </p>
-          <p>
-            Want more information about the eCard and who qualifies to
-            use it? Read the <a href="https://kcls.org/faq/ecards/#ecards">FAQ</a>.
-          </p>
-          <p><b>KCLS eCard is not available to City of Seattle residents.</b></p>
-        </div>
-
-        <div id="eCARD" data-language="en" data-branchid="">
-          <!-- eCARD requires JavaScript in order to display the registration form -->
-          <!-- The following will detect if JavaScript is enabled on the patron's browser -->
-          <noscript>
-            <h2 style="color:red;">Warning - JavaScript Required</h2>
-            <p>
-             For full functionality of this web page it is necessary to enable 
-             JavaScript in your browser. For more information on most browsers, try 
-             <a href="http://www.enable-javascript.com/" target="_blank">How to enable JavaScript</a> 
-             OR <a href="http://activatejavascript.org/en/instructions" target="_blank">activatejavascript.org</a>
-            </p>
-          </noscript>
-        </div>
-      </div>
-    </div>
-
-    <!-- BC FOOTER -->
-    [% ctx.bc_footer %]
-    <!-- BC END FOOTER -->
-
-
-    <!-- QUIPU JS -->
-    <script type="text/javascript" src="https://ecard.quipugroup.net/js/jquery-1.11.1.min.js"></script>
-    <script type="text/javascript" src="https://ecard.quipugroup.net/js/jqueryUI/js/jquery-ui-1.10.4.custom.min.js"></script>
-    <script type="text/javascript" src="https://ecard.quipugroup.net/js/jquery.xdomainrequest.min.js"></script>
-    <script type="text/javascript" src="https://ecard.quipugroup.net/js/jquery.PrintArea.js"></script>
-    <script type="text/javascript" src="https://ecard.quipugroup.net/js/eCARDMain.js"></script>
-    <script type="text/javascript" src="https://ecard.quipugroup.net/Libraries/22/eCARDLibrary.js"></script>
-    <!-- END QUIPU JS -->
-
-    <!-- BC requires jquery, loaded from quipu (above) in this form -->
-    <!-- BC JS -->
-    [% ctx.bc_js %]
-    <!-- BC END JS -->
-
-  </body>
-</html>
-
+[%- PROCESS "opac/parts/header.tt2";
+    PROCESS "opac/parts/org_selector.tt2";
+    WRAPPER "opac/parts/base.tt2";
+    INCLUDE "opac/parts/topnav.tt2";
+    ctx.page_title = l("Request Electronic Card");
+    ctx_org = ctx.physical_loc || ctx.search_ou || ctx.aou_tree.id;
+%]
+<div id="content-wrapper">
+<div id="main-content-register">
+<h2>[% ctx.page_title %]</h2>
+[% IF ctx.ecard.enabled && ctx.ecard.quipu_id %]
+<div id="ecard-intro">
+<!-- The following script tags can be placed in the library's <head> or <body> tag -->
+<script src="https://ecard-us2.quipugroup.net/js/eCARDEmbed.js"></script>
+<script>loadQGeCARD([% ctx.ecard.quipu_id %])</script>
+<p>
+[% l('Fill out the application below to get immediate access to electronic services, such as e-books, audiobooks, magazines, and databases, provided by your local library.') %]
+</p>
+</div>
+<!-- The following <div> tag should be placed on the web page where the library would like the registration form to display -->
+<div id="eCARD" data-language="en" data-branchid="[% ctx_org %]"></div>
+[% ELSE %]
+<p>
+[% l('Electronic card registration is not enabled for this library.') %]
+</p>
+[% END #IF %]
+</div>
+</div>
+[% END #WRAPPER %]
index 80f6a8b..3aefd84 100644 (file)
@@ -8,7 +8,13 @@
     [% ELSE %]
     <a href="http://example.com">[% l('Bottom Link 2') %]</a> &nbsp;|&nbsp;
     [% END %]
+    [% IF ctx.get_org_setting(ctx.physical_loc || ctx.aou_tree_id,
+                              'opac.ecard_registration_enabled') %]
+    <a href="[% mkurl(ctx.opac_root _ '/ecard/form') %]"> [%
+       l('Request Electronic Card') %]</a> &nbsp;|&nbsp;
+    [% ELSE %]
     <a href="http://example.com">[% l('Bottom Link 3') %]</a> &nbsp;|&nbsp;
+    [% END %]
     <a href="http://example.com">[% l('Bottom Link 4') %]</a> &nbsp;|&nbsp;
     <a href="http://example.com">[% l('Bottom Link 5') %]</a>
     [% IF ctx.timing %]