fixed potential SQL error in fr-FR sample itemtypes
[koha.git] / circ / returns.pl
blob9228674abb112d23438ecc4c6d7c6888b6dfd0cb
1 #!/usr/bin/perl
3 # Copyright 2000-2002 Katipo Communications
4 # 2006 SAN-OP
5 # 2007 BibLibre, Paul POULAIN
7 # This file is part of Koha.
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
12 # version.
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along with
19 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 # Suite 330, Boston, MA 02111-1307 USA
22 =head1 returns.pl
24 script to execute returns of books
26 =cut
28 use strict;
29 use CGI;
30 use C4::Context;
31 use C4::Auth qw/:DEFAULT get_session/;
32 use C4::Output;
33 use C4::Circulation;
34 use C4::Dates qw/format_date/;
35 use Date::Calc qw/Add_Delta_Days/;
36 use C4::Calendar;
37 use C4::Print;
38 use C4::Reserves;
39 use C4::Biblio;
40 use C4::Items;
41 use C4::Members;
42 use C4::Branch; # GetBranchName
43 use C4::Koha; # FIXME : is it still useful ?
45 my $query = new CGI;
47 if (!C4::Context->userenv){
48 my $sessionID = $query->cookie("CGISESSID");
49 my $session = get_session($sessionID);
50 if ($session->param('branch') eq 'NO_LIBRARY_SET'){
51 # no branch set we can't return
52 print $query->redirect("/cgi-bin/koha/circ/selectbranchprinter.pl");
53 exit;
57 #getting the template
58 my ( $template, $librarian, $cookie ) = get_template_and_user(
60 template_name => "circ/returns.tmpl",
61 query => $query,
62 type => "intranet",
63 authnotrequired => 0,
64 flagsrequired => { circulate => 1 },
68 #####################
69 #Global vars
70 my $branches = GetBranches();
71 my $printers = GetPrinters();
73 #my $branch = C4::Context->userenv?C4::Context->userenv->{'branch'}:"";
74 my $printer = C4::Context->userenv?C4::Context->userenv->{'branchprinter'}:"";
75 my $overduecharges = (C4::Context->preference('finesMode') && C4::Context->preference('finesMode') ne 'off');
77 # Some code to handle the error if there is no branch or printer setting.....
80 # Set up the item stack ....
81 my %returneditems;
82 my %riduedate;
83 my %riborrowernumber;
84 my @inputloop;
85 foreach ( $query->param ) {
86 (next) unless (/ri-(\d*)/);
87 my %input;
88 my $counter = $1;
89 (next) if ( $counter > 20 );
90 my $barcode = $query->param("ri-$counter");
91 my $duedate = $query->param("dd-$counter");
92 my $borrowernumber = $query->param("bn-$counter");
93 $counter++;
95 # decode barcode
96 $barcode = barcodedecode($barcode) if(C4::Context->preference('itemBarcodeInputFilter'));
98 ######################
99 #Are these lines still useful ?
100 $returneditems{$counter} = $barcode;
101 $riduedate{$counter} = $duedate;
102 $riborrowernumber{$counter} = $borrowernumber;
104 #######################
105 $input{counter} = $counter;
106 $input{barcode} = $barcode;
107 $input{duedate} = $duedate;
108 $input{borrowernumber} = $borrowernumber;
109 push( @inputloop, \%input );
112 ############
113 # Deal with the requests....
115 if ($query->param('WT-itemNumber')){
116 updateWrongTransfer ($query->param('WT-itemNumber'),$query->param('WT-waitingAt'),$query->param('WT-From'));
119 if ( $query->param('resbarcode') ) {
120 my $item = $query->param('itemnumber');
121 my $borrowernumber = $query->param('borrowernumber');
122 my $resbarcode = $query->param('resbarcode');
123 my $diffBranchReturned = $query->param('diffBranch');
124 # set to waiting....
125 my $iteminfo = GetBiblioFromItemNumber($item);
126 # fix up item type for display
127 $iteminfo->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $iteminfo->{'itype'} : $iteminfo->{'itemtype'};
128 my $diffBranchSend;
130 # addin in ModReserveAffect the possibility to check if the document is expected in this library or not,
131 # if not we send a value in reserve waiting for not implementting waiting status
132 if ($diffBranchReturned) {
133 $diffBranchSend = $diffBranchReturned;
135 else {
136 $diffBranchSend = undef;
138 ModReserveAffect( $item, $borrowernumber,$diffBranchSend);
139 # check if we have other reservs for this document, if we have a return send the message of transfer
140 my ( $messages, $nextreservinfo ) = GetOtherReserves($item);
142 my $branchname = GetBranchName( $messages->{'transfert'} );
143 my ($borr) = GetMemberDetails( $nextreservinfo, 0 );
144 my $borcnum = $borr->{'cardnumber'};
145 my $name =
146 $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'};
147 my $slip = $query->param('resslip');
150 if ( $messages->{'transfert'} ) {
151 $template->param(
152 itemtitle => $iteminfo->{'title'},
153 itembiblionumber => $iteminfo->{'biblionumber'},
154 iteminfo => $iteminfo->{'author'},
155 tobranchname => $branchname,
156 name => $name,
157 borrowernumber => $borrowernumber,
158 borcnum => $borcnum,
159 borfirstname => $borr->{'firstname'},
160 borsurname => $borr->{'surname'},
161 diffbranch => 1
166 my $borrower;
167 my $returned = 0;
168 my $messages;
169 my $issueinformation;
170 my $barcode = $query->param('barcode');
171 # strip whitespace
172 # $barcode =~ s/\s*//g; - use barcodedecode for this; whitespace is not invalid.
173 my $exemptfine = $query->param('exemptfine');
174 my $dropboxmode= $query->param('dropboxmode');
175 my $calendar = C4::Calendar->new( branchcode => C4::Context->userenv->{'branch'} );
176 #dropbox: get last open day (today - 1)
177 my $dropboxdate = $calendar->addDate(C4::Dates->new(), -1 );
178 my $dotransfer = $query->param('dotransfer');
179 if ($dotransfer){
180 # An item has been returned to a branch other than the homebranch, and the librarian has choosen to initiate a transfer
181 my $transferitem=$query->param('transferitem');
182 my $tobranch=$query->param('tobranch');
183 ModItemTransfer($transferitem, C4::Context->userenv->{'branch'}, $tobranch);
186 # actually return book and prepare item table.....
187 if ($barcode) {
188 $barcode = barcodedecode($barcode) if(C4::Context->preference('itemBarcodeInputFilter'));
190 # save the return
192 ( $returned, $messages, $issueinformation, $borrower ) =
193 AddReturn( $barcode, C4::Context->userenv->{'branch'}, $exemptfine, $dropboxmode);
194 # get biblio description
195 my $biblio = GetBiblioFromItemNumber($issueinformation->{'itemnumber'});
196 # fix up item type for display
197 $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
199 $template->param(
200 title => $biblio->{'title'},
201 homebranch => $biblio->{'homebranch'},
202 author => $biblio->{'author'},
203 itembarcode => $biblio->{'barcode'},
204 itemtype => $biblio->{'itemtype'},
205 ccode => $biblio->{'ccode'},
206 itembiblionumber => $biblio->{'biblionumber'},
208 if ($returned) {
209 $returneditems{0} = $barcode;
210 $riborrowernumber{0} = $borrower->{'borrowernumber'};
211 $riduedate{0} = $issueinformation->{'date_due'};
212 my %input;
213 $input{counter} = 0;
214 $input{first} = 1;
215 $input{barcode} = $barcode;
216 $input{duedate} = $riduedate{0};
217 $input{borrowernumber} = $riborrowernumber{0};
218 push( @inputloop, \%input );
220 # check if the branch is the same as homebranch
221 # if not, we want to put a message
222 if ( $biblio->{'homebranch'} ne C4::Context->userenv->{'branch'} ) {
223 $template->param( homebranch => $biblio->{'homebranch'} );
226 elsif ( !$messages->{'BadBarcode'} ) {
227 my %input;
228 $input{counter} = 0;
229 $input{first} = 1;
230 $input{barcode} = $barcode;
231 $input{duedate} = 0;
233 $returneditems{0} = $barcode;
234 $riduedate{0} = 0;
235 if ( $messages->{'wthdrawn'} ) {
236 $input{withdrawn} = 1;
237 $input{borrowernumber} = "Item Cancelled";
238 $riborrowernumber{0} = 'Item Cancelled';
240 else {
241 $input{borrowernumber} = " ";
242 $riborrowernumber{0} = ' ';
244 push( @inputloop, \%input );
247 $template->param( inputloop => \@inputloop );
249 my $found = 0;
250 my $waiting = 0;
251 my $reserved = 0;
253 # new op dev : we check if the document must be returned to his homebranch directly,
254 # if the document is transfered, we have warning message .
256 if ( $messages->{'WasTransfered'} ) {
257 $template->param(
258 found => 1,
259 transfer => 1,
263 if ( $messages->{'NeedsTransfer'} ){
264 $template->param(
265 found => 1,
266 needstransfer => 1,
267 itemnumber => $issueinformation->{'itemnumber'}
271 if ( $messages->{'Wrongbranch'} ){
272 $template->param(
273 wrongbranch => 1,
277 # adding a case of wrong transfert, if the document wasn't transfered in the good library (according to branchtransfer (tobranch) BDD)
279 if ( $messages->{'WrongTransfer'} and not $messages->{'WasTransfered'}) {
280 $template->param(
281 WrongTransfer => 1,
282 TransferWaitingAt => $messages->{'WrongTransfer'},
283 WrongTransferItem => $messages->{'WrongTransferItem'},
286 my $reserve = $messages->{'ResFound'};
287 my $branchname = $branches->{ $reserve->{'branchcode'} }->{'branchname'};
288 my ($borr) = GetMemberDetails( $reserve->{'borrowernumber'}, 0 );
289 my $name =
290 $borr->{'surname'} . " " . $borr->{'title'} . " " . $borr->{'firstname'};
291 $template->param(
292 wname => $name,
293 wborfirstname => $borr->{'firstname'},
294 wborsurname => $borr->{'surname'},
295 wbortitle => $borr->{'title'},
296 wborphone => $borr->{'phone'},
297 wboremail => $borr->{'email'},
298 wboraddress => $borr->{'address'},
299 wboraddress2 => $borr->{'address2'},
300 wborcity => $borr->{'city'},
301 wborzip => $borr->{'zipcode'},
302 wborrowernumber => $reserve->{'borrowernumber'},
303 wborcnum => $borr->{'cardnumber'},
304 wtransfertFrom => C4::Context->userenv->{'branch'},
310 # reserve found and item arrived at the expected branch
312 if ( $messages->{'ResFound'}) {
313 my $reserve = $messages->{'ResFound'};
314 my $branchname = $branches->{ $reserve->{'branchcode'} }->{'branchname'};
315 my ($borr) = GetMemberDetails( $reserve->{'borrowernumber'}, 0 );
316 if ( $reserve->{'ResFound'} eq "Waiting" ) {
317 if ( C4::Context->userenv->{'branch'} eq $reserve->{'branchcode'} ) {
318 $template->param( waiting => 1 );
320 else {
321 $template->param( waiting => 0 );
324 $template->param(
325 found => 1,
326 name => $borr->{'surname'} . " " . $borr->{'title'} . " " . $borr->{'firstname'},
327 borfirstname => $borr->{'firstname'},
328 borsurname => $borr->{'surname'},
329 bortitle => $borr->{'title'},
330 borphone => $borr->{'phone'},
331 boremail => $borr->{'email'},
332 boraddress => $borr->{'address'},
333 boraddress2 => $borr->{'address2'},
334 borcity => $borr->{'city'},
335 borzip => $borr->{'zipcode'},
336 borrowernumber => $reserve->{'borrowernumber'},
337 borcnum => $borr->{'cardnumber'},
338 debarred => $borr->{'debarred'},
339 gonenoaddress => $borr->{'gonenoaddress'},
340 currentbranch => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
341 itemnumber => $reserve->{'itemnumber'},
342 barcode => $barcode,
346 if ( $reserve->{'ResFound'} eq "Reserved" ) {
347 # my @da = localtime( time() );
348 # my $todaysdate = sprintf( "%0.2d/%0.2d/%0.4d", ( $datearr[3] + 1 ),( $datearr[4] + 1 ),( $datearr[5] + 1900 ) );
349 # FIXME - use Dates obj , locale. AND, why [4]+1 ??
350 if ( C4::Context->userenv->{'branch'} eq $reserve->{'branchcode'} ) {
351 $template->param( intransit => 0 );
353 else {
354 $template->param( intransit => 1 );
357 $template->param(
358 found => 1,
359 currentbranch => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
360 destbranchname =>
361 $branches->{ $reserve->{'branchcode'} }->{'branchname'},
362 destbranch => $reserve->{'branchcode'},
363 transfertodo => ( C4::Context->userenv->{'branch'} eq $reserve->{'branchcode'} ? 0 : 1 ),
364 reserved => 1,
365 resbarcode => $barcode,
366 # today => $todaysdate,
367 itemnumber => $reserve->{'itemnumber'},
368 borsurname => $borr->{'surname'},
369 bortitle => $borr->{'title'},
370 borfirstname => $borr->{'firstname'},
371 borrowernumber => $reserve->{'borrowernumber'},
372 borcnum => $borr->{'cardnumber'},
373 borphone => $borr->{'phone'},
374 boraddress => $borr->{'address'},
375 boraddress2 => $borr->{'address2'},
376 borsub => $borr->{'suburb'},
377 borcity => $borr->{'city'},
378 borzip => $borr->{'zipcode'},
379 boremail => $borr->{'email'},
380 debarred => $borr->{'debarred'},
381 gonenoaddress => $borr->{'gonenoaddress'},
382 barcode => $barcode
387 # Error Messages
388 my @errmsgloop;
389 foreach my $code ( keys %$messages ) {
391 # warn $code;
392 my %err;
393 my $exit_required_p = 0;
394 if ( $code eq 'BadBarcode' ) {
395 $err{badbarcode} = 1;
396 $err{msg} = $messages->{'BadBarcode'};
398 elsif ( $code eq 'NotIssued' ) {
399 $err{notissued} = 1;
400 $err{msg} = $branches->{ $messages->{'IsPermanent'} }->{'branchname'};
402 elsif ( $code eq 'WasLost' ) {
403 $err{waslost} = 1;
405 elsif ( $code eq 'ResFound' ) {
406 ; # FIXME... anything to do here?
408 elsif ( $code eq 'WasReturned' ) {
409 ; # FIXME... anything to do here?
411 elsif ( $code eq 'WasTransfered' ) {
412 ; # FIXME... anything to do here?
414 elsif ( $code eq 'wthdrawn' ) {
415 $err{withdrawn} = 1;
416 $exit_required_p = 1;
418 elsif ( ( $code eq 'IsPermanent' ) && ( not $messages->{'ResFound'} ) ) {
419 if ( $messages->{'IsPermanent'} ne C4::Context->userenv->{'branch'} ) {
420 $err{ispermanent} = 1;
421 $err{msg} =
422 $branches->{ $messages->{'IsPermanent'} }->{'branchname'};
425 elsif ( $code eq 'WrongTransfer' ) {
426 ; # FIXME... anything to do here?
428 elsif ( $code eq 'WrongTransferItem' ) {
429 ; # FIXME... anything to do here?
431 elsif ( $code eq 'NeedsTransfer' ) {
433 elsif ( $code eq 'Wrongbranch' ) {
436 else {
437 die "Unknown error code $code"; # XXX
439 if (%err) {
440 push( @errmsgloop, \%err );
442 last if $exit_required_p;
444 $template->param( errmsgloop => \@errmsgloop );
446 # patrontable ....
447 if ($borrower) {
448 my $flags = $borrower->{'flags'};
449 my @flagloop;
450 my $flagset;
451 foreach my $flag ( sort keys %$flags ) {
452 my %flaginfo;
453 unless ($flagset) { $flagset = 1; }
454 $flaginfo{redfont} = ( $flags->{$flag}->{'noissues'} );
455 $flaginfo{flag} = $flag;
456 if ( $flag eq 'CHARGES' ) {
457 $flaginfo{msg} = $flag;
458 $flaginfo{charges} = 1;
459 $flaginfo{borrowernumber} = $borrower->{borrowernumber};
461 elsif ( $flag eq 'WAITING' ) {
462 $flaginfo{msg} = $flag;
463 $flaginfo{waiting} = 1;
464 my @waitingitemloop;
465 my $items = $flags->{$flag}->{'itemlist'};
466 foreach my $item (@$items) {
467 my $biblio =
468 GetBiblioFromItemNumber( $item->{'itemnumber'});
469 my %waitingitem;
470 $waitingitem{biblionum} = $biblio->{'biblionumber'};
471 $waitingitem{barcode} = $biblio->{'barcode'};
472 $waitingitem{title} = $biblio->{'title'};
473 $waitingitem{brname} =
474 $branches->{ $biblio->{'holdingbranch'} }
475 ->{'branchname'};
476 push( @waitingitemloop, \%waitingitem );
478 $flaginfo{itemloop} = \@waitingitemloop;
480 elsif ( $flag eq 'ODUES' ) {
481 my $items = $flags->{$flag}->{'itemlist'};
482 my @itemloop;
483 foreach my $item ( sort { $a->{'date_due'} cmp $b->{'date_due'} }
484 @$items )
486 my $biblio =
487 GetBiblioFromItemNumber( $item->{'itemnumber'});
488 my %overdueitem;
489 $overdueitem{duedate} = format_date( $item->{'date_due'} );
490 $overdueitem{biblionum} = $biblio->{'biblionumber'};
491 $overdueitem{barcode} = $biblio->{'barcode'};
492 $overdueitem{title} = $biblio->{'title'};
493 $overdueitem{brname} =
494 $branches->{ $biblio->{'holdingbranch'} }
495 ->{'branchname'};
496 push( @itemloop, \%overdueitem );
498 $flaginfo{itemloop} = \@itemloop;
499 $flaginfo{overdue} = 1;
501 else {
502 $flaginfo{other} = 1;
503 $flaginfo{msg} = $flags->{$flag}->{'message'};
505 push( @flagloop, \%flaginfo );
507 $template->param(
508 flagset => $flagset,
509 flagloop => \@flagloop,
510 riborrowernumber => $borrower->{'borrowernumber'},
511 riborcnum => $borrower->{'cardnumber'},
512 riborsurname => $borrower->{'surname'},
513 ribortitle => $borrower->{'title'},
514 riborfirstname => $borrower->{'firstname'}
518 #set up so only the last 8 returned items display (make for faster loading pages)
519 my $count = 0;
520 my @riloop;
521 foreach ( sort { $a <=> $b } keys %returneditems ) {
522 my %ri;
523 if ( $count < 8 ) {
524 my $barcode = $returneditems{$_};
525 my $duedate = $riduedate{$_};
526 my $overduetext;
527 my $borrowerinfo;
528 if ($duedate) {
529 my @tempdate = split( /-/, $duedate );
530 $ri{year} = $tempdate[0];
531 $ri{month} = $tempdate[1];
532 $ri{day} = $tempdate[2];
533 my $duedatenz = "$tempdate[2]/$tempdate[1]/$tempdate[0]";
534 my @datearr = localtime( time() );
535 my $todaysdate =
536 $datearr[5] . '-'
537 . sprintf( "%0.2d", ( $datearr[4] + 1 ) ) . '-'
538 . sprintf( "%0.2d", $datearr[3] );
539 # FIXME - todaysdate isn't used, and what date _is_ it ?
540 $ri{duedate} = format_date($duedate);
541 my ($borrower) =
542 GetMemberDetails( $riborrowernumber{$_}, 0 );
543 $ri{borrowernumber} = $borrower->{'borrowernumber'};
544 $ri{borcnum} = $borrower->{'cardnumber'};
545 $ri{borfirstname} = $borrower->{'firstname'};
546 $ri{borsurname} = $borrower->{'surname'};
547 $ri{bortitle} = $borrower->{'title'};
549 else {
550 $ri{borrowernumber} = $riborrowernumber{$_};
553 # my %ri;
554 my $biblio = GetBiblioFromItemNumber(GetItemnumberFromBarcode($barcode));
555 # fix up item type for display
556 $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
557 $ri{itembiblionumber} = $biblio->{'biblionumber'};
558 $ri{itemtitle} = $biblio->{'title'};
559 $ri{itemauthor} = $biblio->{'author'};
560 $ri{itemtype} = $biblio->{'itemtype'};
561 $ri{ccode} = $biblio->{'ccode'};
562 $ri{barcode} = $barcode;
564 else {
565 last;
567 $count++;
568 push( @riloop, \%ri );
570 $template->param( riloop => \@riloop );
572 $template->param(
573 genbrname => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
574 genprname => $printers->{$printer}->{'printername'},
575 branchname => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
576 printer => $printer,
577 errmsgloop => \@errmsgloop,
578 exemptfine => $exemptfine,
579 dropboxmode => $dropboxmode,
580 dropboxdate => $dropboxdate->output(),
581 overduecharges => $overduecharges,
584 # actually print the page!
585 output_html_with_http_headers $query, $cookie, $template->output;