);
sub patron_adv_search {
my( $self, $client, $auth, $search_hash,
- $search_limit, $search_sort, $include_inactive, $search_depth ) = @_;
+ $search_limit, $search_sort, $include_inactive, $search_ou ) = @_;
my $e = new_editor(authtoken=>$auth);
return $e->event unless $e->checkauth;
return $e->event unless $e->allowed('VIEW_USER');
+
+ # depth boundary outside of which patrons must opt-in, default to 0
+ my $opt_boundary = 0;
+ $opt_boundary = $U->ou_ancestor_setting_value($e->requestor->ws_ou,'org.patron_opt_boundary') if user_opt_in_enabled($self);
+
return $U->storagereq(
"open-ils.storage.actor.user.crazy_search", $search_hash,
- $search_limit, $search_sort, $include_inactive, $e->requestor->ws_ou, $search_depth);
+ $search_limit, $search_sort, $include_inactive, $e->requestor->ws_ou, $search_ou, $opt_boundary);
}
my $e = new_editor(authtoken => $auth);
return $e->event unless $e->checkauth;
- my $org_id = $e->requestor->ws_ou;
my $user = $e->retrieve_actor_user($user_id) or return $e->event;
return $e->event unless $e->allowed('VIEW_USER', $user->home_ou);
- # user is automatically opted-in at the home org
- return 1 if $user->home_ou eq $org_id;
+ my $ws_org = $e->requestor->ws_ou;
+ # user is automatically opted-in if they are from the local org
+ return 1 if $user->home_ou eq $ws_org;
+
+ # get the boundary setting
+ my $opt_boundary = $U->ou_ancestor_setting_value($e->requestor->ws_ou,'org.patron_opt_boundary');
+
+ # auto opt in if user falls within the opt boundary
+ my $opt_orgs = $U->get_org_descendants($ws_org, $opt_boundary);
+
+ return 1 if grep $_ eq $user->home_ou, @$opt_orgs;
my $vals = $e->search_actor_usr_org_unit_opt_in(
- {org_unit=>$org_id, usr=>$user_id},{idlist=>1});
+ {org_unit=>$opt_orgs, usr=>$user_id},{idlist=>1});
return 1 if @$vals;
return 0;
);
sub create_user_opt_in_at_org {
- my($self, $conn, $auth, $user_id) = @_;
+ my($self, $conn, $auth, $user_id, $org_id) = @_;
my $e = new_editor(authtoken => $auth, xact=>1);
return $e->die_event unless $e->checkauth;
- my $org_id = $e->requestor->ws_ou;
+
+ # if a specific org unit wasn't passed in, get one based on the defaults;
+ if(!$org_id){
+ my $wsou = $e->requestor->ws_ou;
+ # get the default opt depth
+ my $opt_depth = $U->ou_ancestor_setting_value($wsou,'org.patron_opt_default');
+ # get the org unit at that depth
+ my $org = $e->json_query({
+ from => [ 'actor.org_unit_ancestor_at_depth', $wsou, $opt_depth ]})->[0];
+
+ $org_id = $org->{id};
+ }
my $user = $e->retrieve_actor_user($user_id) or return $e->die_event;
return $e->die_event unless $e->allowed('UPDATE_USER', $user->home_ou);
my $sort = shift;
my $inactive = shift;
my $ws_ou = shift;
- my $ws_ou_depth = shift || 0;
+ my $search_org = shift || $ws_ou;
+ my $opt_boundary = shift || 0;
my $penalty_sort = 0;
$ws_ou = actor::org_unit->search( { parent_ou => undef } )->next->id;
}
- my $opt_in_join = '';
+ my $descendants = "actor.org_unit_descendants($search_org)";
+
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)";
+ $opt_in_where = "AND (";
+ $opt_in_where .= "EXISTS (select id FROM $opt_in_table ";
+ $opt_in_where .= " WHERE org_unit in (select (actor.org_unit_ancestors($ws_ou)).id)";
+ $opt_in_where .= " AND usr = users.id) ";
+ $opt_in_where .= "OR";
+ $opt_in_where .= " users.home_ou IN (select (actor.org_unit_descendants($ws_ou,$opt_boundary)).id))";
}
my $penalty_join = '';
SQL
}
- my $descendants = "actor.org_unit_descendants($ws_ou, $ws_ou_depth)";
-
$select = "JOIN ($select) AS search ON (search.id = users.id)" if ($select);
$select = <<" SQL";
SELECT $distinct_list
FROM $u_table AS users $card
JOIN $descendants d ON (d.id = users.home_ou)
$select
- $opt_in_join
$clone_select
$penalty_join
WHERE users.deleted = FALSE