added method to see last X users who checked out a given copy
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Circ.pm
1 package OpenILS::Application::Circ;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
4
5 use OpenILS::Application::Circ::Circulate;
6 use OpenILS::Application::Circ::Rules;
7 use OpenILS::Application::Circ::Survey;
8 use OpenILS::Application::Circ::StatCat;
9 use OpenILS::Application::Circ::Holds;
10 use OpenILS::Application::Circ::Money;
11 use OpenILS::Application::Circ::NonCat;
12 use OpenILS::Application::Circ::CopyLocations;
13
14 use OpenILS::Application::AppUtils;
15 my $apputils = "OpenILS::Application::AppUtils";
16 my $U = $apputils;
17 use OpenSRF::Utils;
18 use OpenILS::Utils::ModsParser;
19 use OpenILS::Event;
20 use OpenSRF::EX qw(:try);
21 use OpenSRF::Utils::Logger qw(:logger);
22 #my $logger = "OpenSRF::Utils::Logger";
23
24
25 # ------------------------------------------------------------------------
26 # Top level Circ package;
27 # ------------------------------------------------------------------------
28
29 sub initialize {
30         my $self = shift;
31         OpenILS::Application::Circ::Rules->initialize();
32         OpenILS::Application::Circ::Circulate->initialize();
33 }
34
35
36 # ------------------------------------------------------------------------
37 # Returns an array of {circ, record} hashes checked out by the user.
38 # ------------------------------------------------------------------------
39 __PACKAGE__->register_method(
40         method  => "checkouts_by_user",
41         api_name        => "open-ils.circ.actor.user.checked_out",
42         NOTES           => <<"  NOTES");
43         Returns a list of open circulations as a pile of objects.  each object
44         contains the relevant copy, circ, and record
45         NOTES
46
47 sub checkouts_by_user {
48         my( $self, $client, $user_session, $user_id ) = @_;
49
50         my( $requestor, $target, $copy, $record, $evt );
51
52         ( $requestor, $target, $evt ) = 
53                 $apputils->checkses_requestor( $user_session, $user_id, 'VIEW_CIRCULATIONS');
54         return $evt if $evt;
55
56         my $circs = $apputils->simplereq(
57                 'open-ils.storage',
58                 "open-ils.storage.direct.action.open_circulation.search.atomic", 
59 #               { usr => $target->id, xact_finish => undef } );
60                 { usr => $target->id } );
61
62         my @results;
63         for my $circ (@$circs) {
64
65                 ( $copy, $evt )  = $apputils->fetch_copy($circ->target_copy);
66                 return $evt if $evt;
67
68                 $logger->debug("Retrieving record for copy " . $circ->target_copy);
69
70                 ($record, $evt) = $apputils->fetch_record_by_copy( $circ->target_copy );
71                 return $evt if $evt;
72
73                 my $mods = $apputils->record_to_mvr($record);
74
75                 push( @results, { copy => $copy, circ => $circ, record => $mods } );
76         }
77
78         return \@results;
79
80 }
81
82
83
84 __PACKAGE__->register_method(
85         method  => "checkouts_by_user_slim",
86         api_name        => "open-ils.circ.actor.user.checked_out.slim",
87         NOTES           => <<"  NOTES");
88         Returns a list of open circulation objects
89         NOTES
90
91 sub checkouts_by_user_slim {
92         my( $self, $client, $user_session, $user_id ) = @_;
93
94         my( $requestor, $target, $copy, $record, $evt );
95
96         ( $requestor, $target, $evt ) = 
97                 $apputils->checkses_requestor( $user_session, $user_id, 'VIEW_CIRCULATIONS');
98         return $evt if $evt;
99
100         $logger->debug( 'User ' . $requestor->id . 
101                 " retrieving checked out items for user " . $target->id );
102
103         return $apputils->simplereq(
104                 'open-ils.storage',
105                 "open-ils.storage.direct.action.open_circulation.search.atomic", 
106 #               { usr => $target->id, xact_finish => undef } );
107                 { usr => $target->id } );
108 }
109
110
111
112
113 __PACKAGE__->register_method(
114         method  => "title_from_transaction",
115         api_name        => "open-ils.circ.circ_transaction.find_title",
116         NOTES           => <<"  NOTES");
117         Returns a mods object for the title that is linked to from the 
118         copy from the hold that created the given transaction
119         NOTES
120
121 sub title_from_transaction {
122         my( $self, $client, $login_session, $transactionid ) = @_;
123
124         my( $user, $circ, $title, $evt );
125
126         ( $user, $evt ) = $apputils->checkses( $login_session );
127         return $evt if $evt;
128
129         ( $circ, $evt ) = $apputils->fetch_circulation($transactionid);
130         return $evt if $evt;
131         
132         ($title, $evt) = $apputils->fetch_record_by_copy($circ->target_copy);
133         return $evt if $evt;
134
135         return $apputils->record_to_mvr($title);
136 }
137
138
139 __PACKAGE__->register_method(
140         method  => "set_circ_lost",
141         api_name        => "open-ils.circ.circulation.set_lost",
142         NOTES           => <<"  NOTES");
143         Params are login, circid
144         login must have SET_CIRC_LOST perms
145         Sets a circulation to lost
146         NOTES
147
148 __PACKAGE__->register_method(
149         method  => "set_circ_lost",
150         api_name        => "open-ils.circ.circulation.set_claims_returned",
151         NOTES           => <<"  NOTES");
152         Params are login, circid
153         login must have SET_CIRC_MISSING perms
154         Sets a circulation to lost
155         NOTES
156
157 sub set_circ_lost {
158         my( $self, $client, $login, $circid ) = @_;
159         my( $user, $circ, $evt );
160
161         ( $user, $evt ) = $apputils->checkses($login);
162         return $evt if $evt;
163
164         ( $circ, $evt ) = $apputils->fetch_circulation( $circid );
165         return $evt if $evt;
166
167         if($self->api_name =~ /lost/) {
168                 if($evt = $apputils->checkperms(
169                         $user->id, $circ->circ_lib, "SET_CIRC_LOST")) {
170                         return $evt;
171                 }
172                 $circ->stop_fines("LOST");              
173         }
174
175         # XXX Back date the checkin time so the patron has no fines
176         if($self->api_name =~ /claims_returned/) {
177                 if($evt = $apputils->checkperms(
178                         $user->id, $circ->circ_lib, "SET_CIRC_CLAIMS_RETURNED")) {
179                         return $evt;
180                 }
181                 $circ->stop_fines("CLAIMSRETURNED");
182         }
183
184         my $s = $apputils->simplereq(
185                 'open-ils.storage',
186                 "open-ils.storage.direct.action.circulation.update", $circ );
187
188         if(!$s) { throw OpenSRF::EX::ERROR ("Error updating circulation with id $circid"); }
189 }
190
191 __PACKAGE__->register_method(
192         method          => "create_in_house_use",
193         api_name                => 'open-ils.circ.in_house_use.create',
194         signature       =>      q/
195                 Creates an in-house use action.
196                 @param $authtoken The login session key
197                 @param params A hash of params including
198                         'location' The org unit id where the in-house use occurs
199                         'copyid' The copy in question
200                         'count' The number of in-house uses to apply to this copy
201                 @return An array of id's representing the id's of the newly created
202                 in-house use objects or an event on an error
203         /);
204
205 sub create_in_house_use {
206         my( $self, $client, $authtoken, $params ) = @_;
207
208         my( $staff, $evt, $copy );
209         my $org         = $params->{location};
210         my $copyid      = $params->{copyid};
211         my $count       = $params->{count} || 1;
212
213         ($staff, $evt) = $U->checkses($authtoken);
214         return $evt if $evt;
215
216         ($copy, $evt) = $U->fetch_copy($copyid);
217         return $evt if $evt;
218
219         $evt = $U->check_perms($staff->id, $org, 'CREATE_IN_HOUSE_USE');
220         return $evt if $evt;
221
222         $logger->activity("User " . $staff->id .
223                 " creating $count in-house use(s) for copy $copyid at location $org");
224
225         my @ids;
226         for(1..$count) {
227                 my $ihu = Fieldmapper::action::in_house_use->new;
228
229                 $ihu->item($copyid);
230                 $ihu->staff($staff->id);
231                 $ihu->org_unit($org);
232                 $ihu->use_time('now');
233
234                 my $id = $U->simplereq(
235                         'open-ils.storage',
236                         'open-ils.storage.direct.action.in_house_use.create', $ihu );
237
238                 return $U->DB_UPDATE_FAILED($ihu) unless $id;
239                 push @ids, $id;
240         }
241
242         return \@ids;
243 }
244
245
246
247 __PACKAGE__->register_method(
248         method  => "view_circ_patrons",
249         api_name        => "open-ils.circ.copy_checkout_history.retrieve",
250         notes           => q/
251                 Retrieves the last X users who checked out a given copy
252                 @param authtoken The login session key
253                 @param copyid The copy to check
254                 @param count How far to go back in the item history
255                 @return An array of patron ids
256         /);
257
258 sub view_circ_patrons {
259         my( $self, $client, $authtoken, $copyid, $count ) = @_; 
260
261         my( $requestor, $evt ) = $U->checksesperm(
262                         $authtoken, 'VIEW_COPY_CHECKOUT_HISTORY' );
263         return $evt if $evt;
264
265         return [] unless $count;
266
267         my $circs = $U->storagereq(
268                 'open-ils.storage.direct.action.circulation.search_where.atomic',
269                         { target_copy => $copyid  }, { limit => $count } );
270
271         my @users;
272         push(@users, $_->usr) for @$circs;
273         return \@users;
274 }
275
276
277 1;