Return Item Barcode in RequestItemResponse
[working/NCIPServer.git] / lib / NCIP / ILS / Koha.pm
1 #
2 #===============================================================================
3 #
4 #         FILE: Koha.pm
5 #
6 #  DESCRIPTION:
7 #
8 #        FILES: ---
9 #         BUGS: ---
10 #        NOTES: ---
11 #       AUTHOR: Chris Cormack (rangi), chrisc@catalyst.net.nz
12 # ORGANIZATION: Koha Development Team
13 #      VERSION: 1.0
14 #      CREATED: 05/11/13 11:14:09
15 #     REVISION: ---
16 #===============================================================================
17 package NCIP::ILS::Koha;
18
19 use Modern::Perl;
20 use Object::Tiny qw{ name };
21
22 use MARC::Record;
23 use MARC::Field;
24
25 use C4::Members qw{ GetMemberDetails };
26 use C4::Circulation qw { AddReturn CanBookBeIssued AddIssue };
27 use C4::Context;
28 use C4::Items qw { GetItem };
29 use C4::Reserves
30   qw {CanBookBeReserved AddReserve GetReservesFromItemnumber CancelReserve GetReservesFromBiblionumber};
31 use C4::Biblio qw {AddBiblio GetMarcFromKohaField GetBiblioData};
32 use C4::Barcodes::ValueBuilder;
33 use C4::Items qw{AddItem};
34
35 sub itemdata {
36     my $self     = shift;
37     my $barcode  = shift;
38     my $itemdata = GetItem( undef, $barcode );
39     if ($itemdata) {
40         return ( $itemdata, undef );
41     }
42     else {
43         return ( undef, 1 );    # item not found error
44     }
45 }
46
47 sub userdata {
48     my $self     = shift;
49     my $userid   = shift;
50     my $userdata = GetMemberDetails( undef, $userid );
51     return $userdata;
52 }
53
54 sub userenv {
55     my $self    = shift;
56     my $branch  = shift || 'AS';
57     my @USERENV = (
58         1,
59         'test',
60         'MASTERTEST',
61         'Test',
62         'Test',
63         $branch,    #branchcode need to set this properly
64         'Auckland',
65         1,
66     );
67
68     C4::Context->_new_userenv('DUMMY_SESSION_ID');
69     C4::Context::set_userenv(@USERENV);
70     return;
71 }
72
73 sub checkin {
74     my $self       = shift;
75     my $barcode    = shift;
76     my $branch     = shift;
77     my $exemptfine = undef;
78     my $dropbox    = undef;
79     $self->userenv();
80     unless ($branch) {
81         my $item = GetItem( undef, $barcode );
82         $branch = $item->{holdingbranch};
83     }
84     ( $success, $messages, $issue, $borrower ) =
85       AddReturn( $barcode, $branch, $exemptfine, $dropbox );
86     my $result = {
87         success         => $success,
88         messages        => $messages,
89         iteminformation => $issue,
90         borrower        => $borrower
91     };
92
93     return $result;
94 }
95
96 sub checkout {
97     my $self     = shift;
98     my $userid   = shift;
99     my $barcode  = shift;
100     my $borrower = GetMemberDetails( undef, $userid );
101     my $item     = GetItem( undef, $barcode );
102     my $error;
103     my $confirm;
104     $self->userenv( $item->{holdingbranch} );
105
106     if ($borrower) {
107
108         ( $error, $confirm ) = CanBookBeIssued( $borrower, $barcode );
109
110         if (%$error) {
111
112             # Can't issue item, return error hash
113             return ( 1, $error );
114         }
115         elsif (%$confirm) {
116             return ( 1, $confirm );
117         }
118         else {
119             my $datedue = AddIssue( $borrower, $barcode );
120             return ( 0, undef, $datedue );    #successfully issued
121         }
122     }
123     else {
124         $error->{'badborrower'} = 1;
125         return ( 1, $error );
126     }
127 }
128
129 sub renew {
130     my $self     = shift;
131     my $barcode  = shift;
132     my $userid   = shift;
133     my $borrower = GetMemberDetails( undef, $userid );
134     if ($borrower) {
135         my $datedue = AddRenewal( $barcode, $borrower->{'borrowernumber'} );
136         my $result = {
137             success => 1,
138             datedue => $datedue
139         };
140         return $result;
141
142     }
143     else {
144         #handle stuff here
145     }
146 }
147
148 sub request {
149     my $self         = shift;
150     my $cardnumber   = shift;
151     my $barcode      = shift;
152     my $biblionumber = shift;
153     my $borrower     = GetMemberDetails( undef, $cardnumber );
154     my $result;
155     unless ($borrower) {
156         $result = { success => 0, messages => { 'BORROWER_NOT_FOUND' => 1 } };
157         return $result;
158     }
159     my $itemdata;
160     if ($barcode) {
161         $itemdata = GetItem( undef, $barcode );
162     }
163     else {
164         $itemdata = GetBiblioData($biblionumber);
165     }
166     unless ($itemdata) {
167         $result = { success => 0, messages => {'ITEM_NOT_FOUND'} };
168         return $result;
169     }
170     $self->userenv();
171     if (
172         CanBookBeReserved(
173             $borrower->{borrowernumber},
174             $itemdata->{biblionumber}
175         )
176       )
177     {
178         my $biblioitemnumber = $itemdata->{biblionumber};
179         my $branchcode       = 'CALG';
180
181         # Add reserve here
182         AddReserve(
183             $branchcode,               $borrower->{borrowernumber},
184             $itemdata->{biblionumber}, 'a',
185             [$biblioitemnumber],       1,
186             undef,                     undef,
187             'Placed By ILL',           '',
188             $itemdata->{'itemnumber'} || undef, undef
189         );
190         my $request_id;
191         if ($biblionumber) {
192             my $reserves = GetReservesFromBiblionumber(
193                 { biblionumber => $itemdata->{biblionumber} } );
194             $request_id = $reserves->[1]->{reserve_id};
195         }
196         else {
197             my ( $reservedate, $borrowernumber, $branchcode2, $reserve_id,
198                 $wait )
199               = GetReservesFromItemnumber( $itemdata->{'itemnumber'} );
200             $request_id = $reserve_id;
201         }
202         $result = {
203             success  => 1,
204             messages => { request_id => $request_id }
205         };
206         return $result;
207     }
208     else {
209         $result = { success => 0, messages => { CANNOT_REQUEST => 1 } };
210         return $result;
211
212     }
213 }
214
215 sub cancelrequest {
216     my $self      = shift;
217     my $requestid = shift;
218     CancelReserve( { reserve_id => $requestid } );
219
220     my $result = { success => 1 };
221     return $result;
222 }
223
224 sub acceptitem {
225     my $self    = shift || die "Not called as a method, we must bail out";
226     my $barcode = shift || die "No barcode passed can not continue";
227     my $user    = shift;
228     my $action  = shift;
229     my $create  = shift;
230     my $iteminfo = shift;
231     my $result;
232
233     $self->userenv();    # set userenvironment
234     my ( $biblionumber, $biblioitemnumber );
235     if ($create) {
236         my $record;
237         my $frameworkcode = 'FA';    # we should get this from config
238
239         # we must make the item first
240         # Autographics workflow is to make the item each time
241         if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
242
243             # TODO
244         }
245         elsif ( C4::Context->preference('marcflavour') eq 'NORMARC' ) {
246
247             #TODO
248         }
249         else {
250             # MARC21
251             # create a marc record
252             $record = MARC::Record->new();
253             $record->leader('     nac  22     1u 4500');
254             $record->insert_fields_ordered(
255                 MARC::Field->new( '100', '1', '0', 'a' => $iteminfo->{author} ),
256                 MARC::Field->new( '245', '1', '0', 'a' => $iteminfo->{title} ),
257                 MARC::Field->new(
258                     '260', '1', '0',
259                     'b' => $iteminfo->{publisher},
260                     'c' => $iteminfo->{publicationdate}
261                 ),
262                 MARC::Field->new(
263                     '942', '1', '0', 'c' => $iteminfo->{mediumtype}
264                 )
265             );
266
267         }
268
269         ( $biblionumber, $biblioitemnumber ) =
270           AddBiblio( $record, $frameworkcode );
271         my $itemnumber;
272
273         my %args;
274         ( $args{tag}, $args{subfield} ) =
275           GetMarcFromKohaField( "items.barcode", '' );
276         my ( $nextnum, $scr ) =
277           C4::Barcodes::ValueBuilder::incremental::get_barcode( \%args );
278         $nextnum = sprintf( "%.0f", $nextnum );
279         my $item = { 'barcode' => $nextnum };
280         ( $biblionumber, $biblioitemnumber, $itemnumber ) =
281           AddItem( $item, $biblionumber );
282         $barcode = $nextnum;
283     }
284
285     # find hold and get branch for that, check in there
286     my $itemdata = GetItem( undef, $barcode );
287
288     my ( $reservedate, $borrowernumber, $branchcode, $reserve_id, $wait ) =
289       GetReservesFromItemnumber( $itemdata->{'itemnumber'} );
290
291     # now we have to check the requested action
292     if ( $action =~ /^Hold For Pickup And Notify/ ) {
293         unless ($reserve_id) {
294             $branchcode = 'CALG';    # set this properly
295                                      # no reserve, place one
296             if ($user) {
297                 my $borrower = GetMemberDetails( undef, $user );
298                 if ($borrower) {
299                     AddReserve(
300                         $branchcode,
301                         $borrower->{'borrowernumber'},
302                         $biblionumber,
303                         'a',
304                         [$biblioitemnumber],
305                         1,
306                         undef,
307                         undef,
308                         'Placed By ILL',
309                         '',
310                         $itemdata->{'itemnumber'},
311                         undef
312                     );
313                 }
314
315                 else {
316                     $result =
317                       { success => 0, messages => { NO_BORROWER => 1 } };
318                     return $result;
319                 }
320             }
321             else {
322                 $result =
323                   { success => 0, messages => { NO_HOLD_BORROWER => 1 } };
324                 return $result;
325             }
326         }
327     }
328     else {
329         unless ($reserve_id) {
330             $result = { success => 0, messages => { NO_HOLD => 1 } };
331             return $result;
332         }
333     }
334     my ( $success, $messages, $issue, $borrower ) =
335       AddReturn( $barcode, $branchcode, undef, undef );
336     if ( $messages->{'NotIssued'} ) {
337         $success = 1
338           ; # we do this because we are only doing the return to trigger the reserve
339     }
340
341     $result = {
342         success         => $success,
343         messages        => $messages,
344         iteminformation => $issue,
345         borrower        => $borrower,
346         newbarcode      => $barcode
347     };
348
349     return $result;
350 }
351 1;