3 # Copyright 2000-2002 Katipo Communications
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
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
24 script to execute returns of books
31 use C4::Auth qw/:DEFAULT get_session/;
34 use C4::Dates qw/format_date/;
35 use Date::Calc qw/Add_Delta_Days/;
42 use C4::Branch; # GetBranchName
43 use C4::Koha; # FIXME : is it still useful ?
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");
58 my ( $template, $librarian, $cookie ) = get_template_and_user(
60 template_name => "circ/returns.tmpl",
64 flagsrequired => { circulate => "circulate_remaining_permissions" },
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 ....
85 foreach ( $query->param ) {
86 (next) unless (/ri-(\d*)/);
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");
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 );
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');
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'};
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 (C4::Context->userenv->{'branch'} ne $diffBranchReturned) {
133 $diffBranchSend = $diffBranchReturned;
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'};
146 $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'};
147 my $slip = $query->param('resslip');
150 if ( $messages->{'transfert'} ) {
152 itemtitle => $iteminfo->{'title'},
153 itembiblionumber => $iteminfo->{'biblionumber'},
154 iteminfo => $iteminfo->{'author'},
155 tobranchname => $branchname,
157 borrowernumber => $borrowernumber,
159 borfirstname => $borr->{'firstname'},
160 borsurname => $borr->{'surname'},
169 my $issueinformation;
170 my $barcode = $query->param('barcode');
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');
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.....
188 $barcode = barcodedecode($barcode) if(C4::Context->preference('itemBarcodeInputFilter'));
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'};
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'},
209 $returneditems{0} = $barcode;
210 $riborrowernumber{0} = $borrower->{'borrowernumber'};
211 $riduedate{0} = $issueinformation->{'date_due'};
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'} ) {
230 $input{barcode} = $barcode;
233 $returneditems{0} = $barcode;
235 if ( $messages->{'wthdrawn'} ) {
236 $input{withdrawn} = 1;
237 $input{borrowernumber} = "Item Cancelled";
238 $riborrowernumber{0} = 'Item Cancelled';
241 $input{borrowernumber} = " ";
242 $riborrowernumber{0} = ' ';
244 push( @inputloop, \%input );
247 $template->param( inputloop => \@inputloop );
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'} ) {
263 if ( $messages->{'NeedsTransfer'} ){
267 itemnumber => $issueinformation->{'itemnumber'}
271 if ( $messages->{'Wrongbranch'} ){
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'}) {
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 );
290 $borr->{'surname'} . " " . $borr->{'title'} . " " . $borr->{'firstname'};
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 );
321 $template->param( waiting => 0 );
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'},
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 );
354 $template->param( intransit => 1 );
359 currentbranch => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
361 $branches->{ $reserve->{'branchcode'} }->{'branchname'},
362 destbranch => $reserve->{'branchcode'},
363 transfertodo => ( C4::Context->userenv->{'branch'} eq $reserve->{'branchcode'} ? 0 : 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'},
389 foreach my $code ( keys %$messages ) {
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' ) {
400 $err{msg} = $branches->{ $messages->{'IsPermanent'} }->{'branchname'};
402 elsif ( $code eq 'WasLost' ) {
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' ) {
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;
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' ) {
437 die "Unknown error code $code"; # XXX
440 push( @errmsgloop, \%err );
442 last if $exit_required_p;
444 $template->param( errmsgloop => \@errmsgloop );
448 my $flags = $borrower->{'flags'};
451 foreach my $flag ( sort keys %$flags ) {
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{chargeamount} = $flags->{$flag}->{amount};
460 $flaginfo{borrowernumber} = $borrower->{borrowernumber};
462 elsif ( $flag eq 'WAITING' ) {
463 $flaginfo{msg} = $flag;
464 $flaginfo{waiting} = 1;
466 my $items = $flags->{$flag}->{'itemlist'};
467 foreach my $item (@$items) {
469 GetBiblioFromItemNumber( $item->{'itemnumber'});
471 $waitingitem{biblionum} = $biblio->{'biblionumber'};
472 $waitingitem{barcode} = $biblio->{'barcode'};
473 $waitingitem{title} = $biblio->{'title'};
474 $waitingitem{brname} =
475 $branches->{ $biblio->{'holdingbranch'} }
477 push( @waitingitemloop, \%waitingitem );
479 $flaginfo{itemloop} = \@waitingitemloop;
481 elsif ( $flag eq 'ODUES' ) {
482 my $items = $flags->{$flag}->{'itemlist'};
484 foreach my $item ( sort { $a->{'date_due'} cmp $b->{'date_due'} }
488 GetBiblioFromItemNumber( $item->{'itemnumber'});
490 $overdueitem{duedate} = format_date( $item->{'date_due'} );
491 $overdueitem{biblionum} = $biblio->{'biblionumber'};
492 $overdueitem{barcode} = $biblio->{'barcode'};
493 $overdueitem{title} = $biblio->{'title'};
494 $overdueitem{brname} =
495 $branches->{ $biblio->{'holdingbranch'} }
497 push( @itemloop, \%overdueitem );
499 $flaginfo{itemloop} = \@itemloop;
500 $flaginfo{overdue} = 1;
503 $flaginfo{other} = 1;
504 $flaginfo{msg} = $flags->{$flag}->{'message'};
506 push( @flagloop, \%flaginfo );
510 flagloop => \@flagloop,
511 riborrowernumber => $borrower->{'borrowernumber'},
512 riborcnum => $borrower->{'cardnumber'},
513 riborsurname => $borrower->{'surname'},
514 ribortitle => $borrower->{'title'},
515 riborfirstname => $borrower->{'firstname'}
519 #set up so only the last 8 returned items display (make for faster loading pages)
522 foreach ( sort { $a <=> $b } keys %returneditems ) {
525 my $barcode = $returneditems{$_};
526 my $duedate = $riduedate{$_};
530 my @tempdate = split( /-/, $duedate );
531 $ri{year} = $tempdate[0];
532 $ri{month} = $tempdate[1];
533 $ri{day} = $tempdate[2];
534 my $duedatenz = "$tempdate[2]/$tempdate[1]/$tempdate[0]";
535 my @datearr = localtime( time() );
538 . sprintf( "%0.2d", ( $datearr[4] + 1 ) ) . '-'
539 . sprintf( "%0.2d", $datearr[3] );
540 # FIXME - todaysdate isn't used, and what date _is_ it ?
541 $ri{duedate} = format_date($duedate);
543 GetMemberDetails( $riborrowernumber{$_}, 0 );
544 $ri{borrowernumber} = $borrower->{'borrowernumber'};
545 $ri{borcnum} = $borrower->{'cardnumber'};
546 $ri{borfirstname} = $borrower->{'firstname'};
547 $ri{borsurname} = $borrower->{'surname'};
548 $ri{bortitle} = $borrower->{'title'};
549 $ri{bornote} = $borrower->{'borrowernotes'};
552 $ri{borrowernumber} = $riborrowernumber{$_};
556 my $biblio = GetBiblioFromItemNumber(GetItemnumberFromBarcode($barcode));
557 # fix up item type for display
558 $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
559 $ri{itembiblionumber} = $biblio->{'biblionumber'};
560 $ri{itemtitle} = $biblio->{'title'};
561 $ri{itemauthor} = $biblio->{'author'};
562 $ri{itemtype} = $biblio->{'itemtype'};
563 $ri{itemnote} = $biblio->{'itemnotes'};
564 $ri{ccode} = $biblio->{'ccode'};
565 $ri{itemnumber} = $biblio->{'itemnumber'};
566 $ri{barcode} = $barcode;
572 push( @riloop, \%ri );
574 $template->param( riloop => \@riloop );
577 genbrname => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
578 genprname => $printers->{$printer}->{'printername'},
579 branchname => $branches->{C4::Context->userenv->{'branch'}}->{'branchname'},
581 errmsgloop => \@errmsgloop,
582 exemptfine => $exemptfine,
583 dropboxmode => $dropboxmode,
584 dropboxdate => $dropboxdate->output(),
585 overduecharges => $overduecharges,
588 # actually print the page!
589 output_html_with_http_headers $query, $cookie, $template->output;