6edd5a4c8e523a380ddd16af0f3534a8069232d5
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Circ / Holds.pm
1 # ---------------------------------------------------------------
2 # Copyright (C) 2005  Georgia Public Library Service 
3 # Bill Erickson <highfalutin@gmail.com>
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 # ---------------------------------------------------------------
15
16
17 package OpenILS::Application::Circ::Holds;
18 use base qw/OpenSRF::Application/;
19 use strict; use warnings;
20 use OpenILS::Application::AppUtils;
21 my $apputils = "OpenILS::Application::AppUtils";
22 use OpenILS::EX;
23 use OpenILS::Perm;
24
25
26
27 __PACKAGE__->register_method(
28         method  => "create_hold",
29         api_name        => "open-ils.circ.holds.create",
30         notes           => <<NOTE);
31 Create a new hold for an item.  From a permissions perspective, 
32 the login session is used as the 'requestor' of the hold.  
33 The hold recipient is determined by the 'usr' setting within
34 the hold object.
35
36 First we verify the requestion has holds request permissions.
37 Then we verify that the recipient is allowed to make the given hold.
38 If not, we see if the requestor has "override" capabilities.  If not,
39 a permission exception is returned.  If permissions allow, we cycle
40 through the set of holds objects and create.
41
42 If the recipient does not have permission to place multiple holds
43 on a single title and said operation is attempted, a permission
44 exception is returned
45 NOTE
46
47 sub create_hold {
48         my( $self, $client, $login_session, @holds) = @_;
49
50         if(!@holds){return 0;}
51         my $user = $apputils->check_user_session($login_session);
52
53
54         my $holds;
55         if(ref($holds[0]) eq 'ARRAY') {
56                 $holds = $holds[0];
57         } else { $holds = [ @holds ]; }
58
59         warn "Iterating over holds requests...\n";
60
61         for my $hold (@$holds) {
62
63                 if(!$hold){next};
64                 my $type = $hold->hold_type;
65
66                 use Data::Dumper;
67                 warn "Hold to create: " . Dumper($hold) . "\n";
68
69                 my $recipient;
70                 if($user->id ne $hold->usr) {
71
72                 } else {
73                         $recipient = $user;
74                 }
75
76                 #enforce the fact that the login is the one requesting the hold
77                 $hold->requestor($user->id); 
78
79                 my $perm = undef;
80
81                 # see if the requestor even has permission to request
82                 if($hold->requestor ne $hold->usr) {
83                         $perm = _check_request_holds_perm($type, $user->id, $user->home_ou);
84                         if($perm) { return $perm; }
85                 }
86
87                 $perm = _check_holds_perm($type, $hold->usr, $recipient->home_ou);
88                 if($perm) { 
89                         #if there is a requestor, see if the requestor has override privelages
90                         if($hold->requestor ne $hold->usr) {
91                                 $perm = _check_request_holds_override($user->id, $user->home_ou);
92                                 if($perm) {return $perm;}
93                         } else {
94                                 return $perm; 
95                         }
96                 }
97
98
99                 #my $session = $apputils->start_db_session();
100                 my $session = OpenSRF::AppSession->create("open-ils.storage");
101                 my $method = "open-ils.storage.direct.action.hold_request.create";
102                 warn "Sending hold request to storage... $method \n";
103
104                 my $req = $session->request( $method, $hold );
105
106                 my $resp = $req->gather(1);
107                 $session->disconnect();
108                 if(!$resp) { return OpenILS::EX->new("UNKNOWN")->ex(); }
109 #               $apputils->commit_db_session($session);
110         }
111
112         return 1;
113 }
114
115 # makes sure that a user has permission to place the type of requested hold
116 # returns the Perm exception if not allowed, returns undef if all is well
117 sub _check_holds_perm {
118         my($type, $user_id, $org_id) = @_;
119
120         if($type eq "M") {
121                 if($apputils->check_user_perms($user_id, $org_id, "MR_HOLDS")) {
122                         return OpenILS::Perm->new("MR_HOLDS");
123                 } 
124
125         } elsif ($type eq "T") {
126                 if($apputils->check_user_perms($user_id, $org_id, "TITLE_HOLDS")) {
127                         return OpenILS::Perm->new("TITLE_HOLDS");
128                 }
129
130         } elsif($type eq "V") {
131                 if($apputils->check_user_perms($user_id, $org_id, "VOLUME_HOLDS")) {
132                         return OpenILS::Perm->new("VOLUME_HOLDS");
133                 }
134
135         } elsif($type eq "C") {
136                 if($apputils->check_user_perms($user_id, $org_id, "COPY_HOLDS")) {
137                         return OpenILS::Perm->new("COPY_HOLDS");
138                 }
139         }
140
141         return undef;
142 }
143
144 # tests if the given user is allowed to place holds on another's behalf
145 sub _check_request_holds_perm {
146         my $user_id = shift;
147         my $org_id = shift;
148         if($apputils->check_user_perms($user_id, $org_id, "REQUEST_HOLDS")) {
149                 return OpenILS::Perm->new("REQUEST_HOLDS");
150         }
151 }
152
153 sub _check_request_holds_override {
154         my $user_id = shift;
155         my $org_id = shift;
156         if($apputils->check_user_perms($user_id, $org_id, "REQUEST_HOLDS_OVERRIDE")) {
157                 return OpenILS::Perm->new("REQUEST_HOLDS_OVERRIDE");
158         }
159 }
160
161
162 __PACKAGE__->register_method(
163         method  => "retrieve_holds",
164         api_name        => "open-ils.circ.holds.retrieve",
165         notes           => <<NOTE);
166 Retrieves all the holds for the specified user id.  The login session
167 is the requestor and if the requestor is different from the user, then
168 the requestor must have VIEW_HOLDS permissions.
169 NOTE
170
171 sub retrieve_holds {
172         my($self, $client, $login_session, $user_id) = @_;
173
174         my $user = $apputils->check_user_session($login_session);
175
176         if($user->id ne $user_id) {
177                 if($apputils->check_user_perms($user->id, $user->home_ou, "VIEW_HOLDS")) {
178                         return OpenILS::Perm->new("VIEW_HOLDS");
179                 }
180         }
181
182         my $session = OpenSRF::AppSession->create("open-ils.storage");
183         my $req = $session->request(
184                 "open-ils.storage.direct.action.hold_request.search.usr.atomic",
185                 $user_id );
186         my $h = $req->gather(1);
187         $session->disconnect();
188         return $h;
189 }
190
191
192 __PACKAGE__->register_method(
193         method  => "cancel_hold",
194         api_name        => "open-ils.circ.hold.cancel",
195         notes           => <<"  NOTE");
196         Cancels the specified hold.  The login session
197         is the requestor and if the requestor is different from the usr field
198         on the hold, the requestor must have CANCEL_HOLDS permissions.
199         NOTE
200
201 sub cancel_hold {
202         my($self, $client, $login_session, $hold) = @_;
203
204         my $user = $apputils->check_user_session($login_session);
205
206         if($user->id ne $hold->usr) {
207                 if($apputils->check_user_perms($user->id, $user->home_ou, "CANCEL_HOLDS")) {
208                         return OpenILS::Perm->new("CANCEL_HOLDS");
209                 }
210         }
211
212         use Data::Dumper;
213         warn "Cancelling hold: " . Dumper($hold) . "\n";
214
215         my $session = OpenSRF::AppSession->create("open-ils.storage");
216         my $req = $session->request(
217                 "open-ils.storage.direct.action.hold_request.delete",
218                 $hold );
219         my $h = $req->gather(1);
220
221         warn "[$h] returned from hold_request delete\n";
222         $session->disconnect();
223         return $h;
224 }
225
226
227 __PACKAGE__->register_method(
228         method  => "update_hold",
229         api_name        => "open-ils.circ.hold.update",
230         notes           => <<"  NOTE");
231         Updates the specified hold.  The login session
232         is the requestor and if the requestor is different from the usr field
233         on the hold, the requestor must have UPDATE_HOLDS permissions.
234         NOTE
235
236 sub update_hold {
237         my($self, $client, $login_session, $hold) = @_;
238
239         my $user = $apputils->check_user_session($login_session);
240
241         if($user->id ne $hold->usr) {
242                 if($apputils->check_user_perms($user->id, $user->home_ou, "UPDATE_HOLDS")) {
243                         return OpenILS::Perm->new("UPDATE_HOLDS");
244                 }
245         }
246
247         use Data::Dumper;
248         warn "Updating hold: " . Dumper($hold) . "\n";
249
250         my $session = OpenSRF::AppSession->create("open-ils.storage");
251         my $req = $session->request(
252                 "open-ils.storage.direct.action.hold_request.update", $hold );
253         my $h = $req->gather(1);
254
255         warn "[$h] returned from hold_request update\n";
256         $session->disconnect();
257         return $h;
258 }
259
260
261
262
263 1;