settings server controlled opt-in functionallity for non-home_ou transactions
authormiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 15 Aug 2007 13:30:17 +0000 (13:30 +0000)
committermiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 15 Aug 2007 13:30:17 +0000 (13:30 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@7665 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/fm_IDL.xml
Open-ILS/examples/opensrf.xml.example
Open-ILS/src/perlmods/OpenILS/Application/Storage/CDBI/actor.pm
Open-ILS/src/perlmods/OpenILS/Application/Storage/Driver/Pg/dbi.pm
Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/actor.pm
Open-ILS/src/sql/Pg/005.schema.actors.sql

index 7d721d4..687cfe2 100644 (file)
 
 
        <!-- Actually in the DB -->
+       <class id="auoi" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_org_unit_opt_in" oils_persist:tablename="actor.usr_org_unit_opt_in" reporter:label="User Sharing Opt-in">
+               <fields oils_persist:primary="id" oils_persist:sequence="actor.usr_org_unit_opt_in_id_seq">
+                       <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
+                       <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
+                       <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
+                       <field reporter:label="Opt-in ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="id"/>
+                       <field reporter:label="Workstation" name="opt_in_ws" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="link"/>
+                       <field reporter:label="Staff Member" name="staff" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="link"/>
+                       <field reporter:label="User" name="usr" oils_obj:array_position="6" oils_persist:virtual="false" reporter:datatype="link"/>
+                       <field reporter:label="Allowed Org Unit" name="org_unit" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="link"/>
+                       <field reporter:label="Opt-in Date/Time" name="opt_in_ts" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+               </fields>
+               <links>
+                       <link field="org_unit" reltype="has_a" key="id" map="" class="aou"/>
+                       <link field="usr" reltype="has_a" key="id" map="" class="au"/>
+                       <link field="staff" reltype="has_a" key="id" map="" class="au"/>
+                       <link field="opt_in_ws" reltype="has_a" key="id" map="" class="aws"/>
+               </links>
+       </class>
+
        <class id="aws" controller="open-ils.cstore" oils_obj:fieldmapper="actor::workstation" oils_persist:tablename="actor.workstation" reporter:label="Workstation">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.workstation_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
index d6d853c..5f5e7d0 100644 (file)
@@ -17,8 +17,18 @@ Example opensrf config file for OpenILS
             <script_lib>/openils/var</script_lib>
         </dirs>
 
+       <!-- global data visiblity settings -->
+        <share>
+               <user>
+                       <!-- Set to "true" to require patron opt-in for foreign (non-home_ou) transactions -->
+                       <opt_in>false</opt_in>
+               </user>
+       </share>
+
         <IDL>/openils/conf/fm_IDL.xml</IDL> <!-- top level IDL file -->
+
         <server_type>prefork</server_type> <!-- net::server type -->
+
         <ils_events>/openils/var/data/ils_events.xml</ils_events> <!-- ILS events description file -->
         
         <email_notify>
index c2e631b..9f7ba25 100644 (file)
@@ -21,6 +21,13 @@ __PACKAGE__->columns( Essential => qw/usrname email first_given_name
                                day_phone evening_phone other_phone mailing_address/ );
 
 #-------------------------------------------------------------------------------
+package actor::usr_org_unit_opt_in;
+use base qw/actor/;
+__PACKAGE__->table( 'actor_usr_org_unit_opt_in' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/org_unit usr staff opt_in_ts opt_in_ws/ );
+
+#-------------------------------------------------------------------------------
 package actor::org_unit_proximity;
 use base qw/actor/;
 __PACKAGE__->table( 'actor_org_unit_proximity' );
index 1bbdd6c..fdd10d2 100644 (file)
        actor::org_address->sequence( 'actor.org_address_id_seq' );
        
        #---------------------------------------------------------------------
+       package actor::usr_org_unit_opt_in;
+       
+       actor::usr_org_unit_opt_in->table( 'actor.usr_org_unit_opt_in' );
+       actor::usr_org_unit_opt_in->sequence( 'actor.usr_org_unit_opt_in_id_seq' );
+
+       #---------------------------------------------------------------------
        package actor::org_unit_proximity;
        
        actor::org_unit_proximity->table( 'actor.org_unit_proximity' );
index 406c06b..2234a27 100644 (file)
@@ -4,6 +4,7 @@ use OpenILS::Application::Storage::CDBI::actor;
 use OpenSRF::Utils::Logger qw/:level/;
 use OpenSRF::Utils qw/:datetime/;
 use OpenILS::Utils::Fieldmapper;
+use OpenSRF::Utils::SettingsClient;
 
 use DateTime;           
 use DateTime::Format::ISO8601;  
@@ -438,6 +439,10 @@ sub patron_search {
        my $limit = shift || 1000;
        my $sort = shift;
        my $inactive = shift;
+       my $ws_ou = shift;
+       my $ws_ou_depth = shift || 0;
+
+       my $strict_opt_in = OpenSRF::Utils::SettingsClient->new->config_value( share => user => 'opt_in' );
 
        $sort = ['family_name','first_given_name'] unless ($$sort[0]);
        push @$sort,'id';
@@ -495,6 +500,8 @@ sub patron_search {
 
        my $u_table = actor::user->table;
        my $a_table = actor::user_address->table;
+       my $opt_in_table = actor::usr_org_unit_opt_in->table;
+       my $ou_table = actor::org_unit->table;
 
        my $u_select = "SELECT id as id FROM $u_table u WHERE $usr_where";
        my $a_select = "SELECT usr as id FROM $a_table a WHERE $addr_where";
@@ -525,12 +532,29 @@ sub patron_search {
                $inactive = 'AND users.active = TRUE';
        }
 
+       if (!$ws_ou) {  # XXX This should be required!!
+               $ws_ou = actor::org_unit->search( { parent_ou => undef } )->[0]->id;
+       }
+
+       my $opt_in_join = '';
+       my $opt_in_where = '';
+       if (lc($strict_opt_in) eq 'true') {
+               $opt_in_join = "LEFT JOIN $opt_in_table oi ON (oi.org_unit = $ws_ou AND users.id = oi.usr)";
+               $opt_in_where = "AND (oi.id IS NOT NULL OR users.home_ou = $ws_ou)";
+       }
+
+       my $descendants = "actor.org_unit_descendants($ws_ou, $ws_ou_depth)";
+
        $select = <<"   SQL";
                SELECT  DISTINCT $distinct_list
                  FROM  $u_table AS users
                        JOIN ($select) AS search USING (id)
+                       JOIN $descendants d ON (d.id = users.home_ou)
+                       $opt_in_join
                        $clone_select
-                 WHERE users.deleted = FALSE $inactive
+                 WHERE users.deleted = FALSE
+                       $inactive
+                       $opt_in_where
                  ORDER BY $order_by
                  LIMIT $limit
        SQL
index 294bb04..d783c5e 100644 (file)
@@ -436,6 +436,16 @@ CREATE TABLE actor.workstation (
        owning_lib      INT     NOT NULL REFERENCES actor.org_unit (id)
 );
 
+CREATE TABLE actor.usr_org_unit_opt_in (
+       id              SERIAL                          PRIMARY KEY,
+       org_unit        INT                             NOT NULL REFERENCES actor.org_unit (id),
+       usr             INT                             NOT NULL REFERENCES actor.usr (id),
+       staff           INT                             NOT NULL REFERENCES actor.usr (id),
+       opt_in_ts       TIMESTAMP WITH TIME ZONE        NOT NULL DEFAULT NOW(),
+       opt_in_ws       INT                             NOT NULL REFERENCES actor.workstation (id),
+       CONSTRAINT usr_opt_in_once_per_org_unit UNIQUE (usr,org_unit)
+);
+
 CREATE TABLE actor.org_unit_setting (
        id              BIGSERIAL       PRIMARY KEY,
        org_unit        INT             NOT NULL REFERENCES actor.org_unit ON DELETE CASCADE,