3 # Copyright 2000-2002 Katipo Communications
4 # This file is part of Koha.
6 # Koha is free software; you can redistribute it and/or modify it under the
7 # terms of the GNU General Public License as published by the Free Software
8 # Foundation; either version 2 of the License, or (at your option) any later
11 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
12 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License along with
16 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
17 # Suite 330, Boston, MA 02111-1307 USA
25 use MARC::File::USMARC;
29 # FIXME - C4::Search uses C4::Reserves2, which uses C4::Search.
30 # So Perl complains that all of the functions here get redefined.
33 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
35 # set the version for version checking
36 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
37 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
41 C4::Search - Functions for searching the Koha catalog and other databases
47 my ($count, @results) = catalogsearch4($env, $type, $search, $num, $offset);
51 This module provides the searching facilities for the Koha catalog and
64 &barcodes &ItemInfo &itemcount
65 &getcoverPhoto &add_query_line
66 &FindDuplicate &ZEBRAsearch_kohafields &sqlsearch &cataloguing_search
67 &getMARCnotes &getMARCsubjects &getMARCurls &parsefields);
68 # make all your functions, whether exported or not;
71 ZEBRAsearchkohafields is the underlying API for searching zebra for KOHA internal use
72 its kept similar to earlier version Koha Marc searches. instead of passing marc tags to the routine
73 you pass named kohafields
74 So you give an array of @kohafieldnames,@values, what relation they have @relations (equal, truncation etc) @and_or and
75 you receive an array of XML records.
76 The routine also has a flag $fordisplay and if it is set to 1 it will return the @results as an array of Perl hashes so that your previous
77 search results templates do actually work.
78 However more advanced search frontends will be available and this routine can serve as the connecting API for circulation and serials management
79 See sub FindDuplicates for an example;
85 sub ZEBRAsearch_kohafields{
86 my ($kohafield,$value, $relation,$sort, $and_or, $fordisplay,$reorder,$startfrom,$number_of_results,$searchfrom)=@_;
87 return (0,0) unless (@$value[0]);
88 my $server="biblioserver";
95 for ( $i=0; $i<=$#{$value}; $i++){
96 last if (@$value[$i] eq "");
98 my $keyattr=MARCfind_attr_from_kohafield(@$kohafield[$i]) if (@$kohafield[$i]);
99 if (!$keyattr){$keyattr=" \@attr 1=any";}
100 @$value[$i]=~ s/(\.|\?|\;|\=|\/|\\|\||\:|\*|\!|\,|\(|\)|\[|\]|\{|\}|\/)/ /g;
101 $query.=@$relation[$i]." ".$keyattr." \"".@$value[$i]."\" " if @$value[$i];
103 for (my $z= 0;$z<=$#{$and_or};$z++){
104 $query=@$and_or[$z]." ".$query if (@$value[$z+1] ne "");
110 ($oConnection[0])=C4::Context->Zconn($server);
115 my (@sortpart)=split /,/,$reorder;
119 my ($sortattr)=MARCfind_attr_from_kohafield($sortpart[0]);
120 my @sortfield=split /@/,$sortattr; ## incase our $sortattr contains type modifiers
121 $query.=" \@attr 7=".$sortpart[1]." \@".$sortfield[1]." 0";##
122 $query= "\@or ".$query;
124 my (@sortpart)=split /,/,$sort;
126 push @sortpart,1; ## Ascending by default
128 my ($sortattr)=MARCfind_attr_from_kohafield($sortpart[0]);
129 my @sortfield=split /@/,$sortattr; ## incase our $sortattr contains type modifiers
130 $query.=" \@attr 7=".$sortpart[1]." \@".$sortfield[1]." 0";## fix to accept secondary sort as well
131 $query= "\@or ".$query;
133 unless($query=~/4=109/){ ###ranked sort not valid for numeric fields
135 $query="\@attr 2=102 ".$query;
146 $oResult= $oConnection[0]->search_pqf($query);
149 while (($i = ZOOM::event(\@oConnection)) != 0) {
150 $event = $oConnection[$i-1]->last_event();
151 last if $event == ZOOM::Event::ZEND;
154 my($error, $errmsg, $addinfo, $diagset) = $oConnection[0]->error_x();
155 if ($error==10007 && $tried<3) {## timeout --another 30 looonng seconds for this update
158 }elsif ($error==2 && $tried<2) {## timeout --temporary zebra error !whatever that means
162 warn "Error-$server /errcode:, $error, /MSG:,$errmsg,$addinfo \n";
164 $oConnection[0]->destroy();
165 return (undef,undef);
167 my $dbh=C4::Context->dbh;
168 $numresults=$oResult->size() ;
174 $ri=$startfrom if $startfrom;
175 for ( $ri; $ri<$numresults ; $ri++){
176 my $xmlrecord=$oResult->record($ri)->raw();
178 ### Turn into hash of xml
179 $xmlrecord=XML_xml2hash($xmlrecord);
182 push @results,$xmlrecord;
183 last if ($number_of_results && $z>=$number_of_results);
188 my (@parsed)=parsefields($dbh,$searchfrom,@results);
189 return ($numresults,@parsed) ;
194 $oConnection[0]->destroy();
195 return ($numresults,@results) ;
199 =item add_bold_fields
200 After a search the searched keyword is <b>boldened</b> in the displayed search results if it exists in the title or author
201 It is now depreceated
203 sub add_html_bold_fields {
204 my ($type, $data, $search) = @_;
205 foreach my $key ('title', 'author') {
208 $new_key = 'bold_' . $key;
209 $data->{$new_key} = $data->{$key};
219 if ($type eq 'keyword') {
220 my $newkey=$search->{'keyword'};
222 @keys = split " ", $newkey;
225 for ($i = 0; $i < $count ; $i++) {
227 if (($data->{$new_key} =~ /($keys[$i])/i) && (lc($keys[$i]) ne 'b') ) {
229 $data->{$new_key} =~ s/$word/<b>$word<\/b>/;
238 ## This searches the SQL database only for biblionumber,itemnumber,barcode
239 ### Not very useful on production but as a debug tool useful during system maturing for ZEBRA operations
241 my ($dbh,$search)=@_;
243 if ($search->{'barcode'} ne '') {
244 $sth=$dbh->prepare("SELECT biblionumber from items where barcode=?");
245 $sth->execute($search->{'barcode'});
246 }elsif ($search->{'itemnumber'} ne '') {
247 $sth=$dbh->prepare("SELECT biblionumber from items where itemnumber=?");
248 $sth->execute($search->{'itemnumber'});
249 }elsif ($search->{'biblionumber'} ne '') {
250 $sth=$dbh->prepare("SELECT biblionumber from biblio where biblionumber=?");
251 $sth->execute($search->{'biblionumber'});
253 return (undef,undef);
256 my $result=$sth->fetchrow_hashref;
257 return (1,$result) if $result;
260 sub cataloguing_search{
261 ## This is an SQL based search designed to be used when adding a new biblio incase library sets
262 ## preference zebraorsql to sql when adding a new biblio
263 my ($search,$num,$offset) = @_;
264 my ($count,@results);
265 my $dbh=C4::Context->dbh;
268 my $condition="select SQL_CALC_FOUND_ROWS marc from biblio where ";
269 if ($search->{'isbn'} ne''){
270 $search->{'isbn'}=$search->{'isbn'}."%";
271 $query=$search->{'isbn'};
272 $condition.= " isbn like ? ";
274 return (0,undef) unless $search->{title};
275 $query=$search->{'title'};
276 $condition.= " MATCH (title) AGAINST(? in BOOLEAN MODE ) ";
278 my $sth=$dbh->prepare($condition);
279 $sth->execute($query);
280 my $nbresult=$dbh->prepare("SELECT FOUND_ROWS()");
282 my $count=$nbresult->fetchrow;
283 my $limit = $num + $offset;
284 my $startfrom = $offset;
287 while (my $marc=$sth->fetchrow){
288 if (($i >= $startfrom) && ($i < $limit)) {
289 my $record=MARC::File::USMARC::decode($marc);
290 my $data=MARCmarc2koha($dbh,$record,"biblios");
296 return ($count,@results);
303 my $dbh=C4::Context->dbh;
304 my $result = MARCmarc2koha($dbh,$record,"biblios");
310 # search duplicate on ISBN, easy and fast..
312 if ($result->{isbn}) {
313 push @kohafield,"isbn";
314 ###Temporary fix for ISBN
315 my $isbn=$result->{isbn};
316 $isbn=~ s/(\.|\?|\;|\=|\/|\\|\||\:|\!|\'|,|\-|\"|\*|\(|\)|\[|\]|\{|\}|\/)//g;
319 $result->{title}=~s /\\//g;
320 $result->{title}=~s /\"//g;
321 $result->{title}=~ s/(\.|\?|\;|\=|\/|\\|\||\:|\*|\!|\,|\-|\(|\)|\[|\]|\{|\}|\/)/ /g;
323 push @kohafield,"title";
324 push @value,$result->{title};
325 push @relation,"\@attr 6=3 \@attr 4=1 \@attr 5=1"; ## right truncated,phrase,whole field
328 my ($total,@result)=ZEBRAsearch_kohafields(\@kohafield,\@value,\@relation,"",\@and_or,0,"",0,1);
330 my $title=XML_readline($result[0],"title","biblios") ;
331 my $biblionumber=XML_readline($result[0],"biblionumber","biblios") ;
332 return $biblionumber,$title ;
340 my ($type,$search,$results)=@_;
341 my $dbh = C4::Context->dbh;
344 my $borrowernumber = $search->{'borrowernumber'};
345 my $remote_IP = $search->{'remote_IP'};
346 my $remote_URL= $search->{'remote_URL'};
347 my $searchdesc = $search->{'searchdesc'};
349 my $sth = $dbh->prepare("INSERT INTO phrase_log(phr_phrase,phr_resultcount,phr_ip,user,actual) VALUES(?,?,?,?,?)");
352 $sth->execute($searchdesc,$results,$remote_IP,$borrowernumber,$remote_URL);
360 @results = &ItemInfo($env, $biblionumber, $type);
362 Returns information about books with the given biblionumber.
364 C<$type> may be either C<intra> or anything else. If it is not set to
365 C<intra>, then the search will exclude lost, very overdue, and
370 C<&ItemInfo> returns a list of references-to-hash. Each element
371 contains a number of keys. Most of them are table items from the
372 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
373 Koha database. Other keys include:
377 =item C<$data-E<gt>{branchname}>
379 The name (not the code) of the branch to which the book belongs.
381 =item C<$data-E<gt>{datelastseen}>
383 This is simply C<items.datelastseen>, except that while the date is
384 stored in YYYY-MM-DD format in the database, here it is converted to
385 DD/MM/YYYY format. A NULL date is returned as C<//>.
387 =item C<$data-E<gt>{datedue}>
389 =item C<$data-E<gt>{class}>
391 This is the concatenation of C<biblioitems.classification>, the book's
392 Dewey code, and C<biblioitems.subclass>.
394 =item C<$data-E<gt>{ocount}>
396 I think this is the number of copies of the book available.
398 =item C<$data-E<gt>{order}>
400 If this is set, it is set to C<One Order>.
407 my ($dbh,$data) = @_;
410 my ($date_due, $count_reserves);
412 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
413 $isth->execute($data->{'itemnumber'});
414 if (my $idata=$isth->fetchrow_hashref){
415 $data->{borrowernumber} = $idata->{borrowernumber};
416 $data->{cardnumber} = $idata->{cardnumber};
417 $datedue = format_date($idata->{'date_due'});
419 if ($datedue eq '' || $datedue eq "0000-00-00"){
421 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
423 $count_reserves = $restype;
427 #get branch information.....
428 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
429 $bsth->execute($data->{'holdingbranch'});
430 if (my $bdata=$bsth->fetchrow_hashref){
431 $data->{'branchname'} = $bdata->{'branchname'};
433 my $date=substr($data->{'datelastseen'},0,8);
434 $data->{'datelastseen'}=format_date($date);
435 $data->{'datedue'}=$datedue;
436 $data->{'count_reserves'} = $count_reserves;
437 # get notforloan complete status if applicable
438 my ($tagfield,$tagsub)=MARCfind_marc_from_kohafield("notforloan","holdings");
439 my $sthnflstatus = $dbh->prepare("select authorised_value from holdings_subfield_structure where tagfield='$tagfield' and tagsubfield='$tagsub'");
440 $sthnflstatus->execute;
441 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
442 if ($authorised_valuecode) {
443 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
444 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
445 my ($lib) = $sthnflstatus->fetchrow;
446 $data->{notforloan} = $lib;
449 # my shelf procedures
450 my ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("shelf","holdings");
452 my $shelfstatus = $dbh->prepare("select authorised_value from holdings_subfield_structure where tagfield='$tagfield' and tagsubfield='$tagsubfield'");
453 $shelfstatus->execute;
454 $authorised_valuecode = $shelfstatus->fetchrow;
455 if ($authorised_valuecode) {
456 $shelfstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
457 $shelfstatus->execute($authorised_valuecode,$data->{shelf});
459 my ($lib) = $shelfstatus->fetchrow;
460 $data->{shelf} = $lib;
474 @barcodes = &barcodes($biblioitemnumber);
476 Given a biblioitemnumber, looks up the corresponding items.
478 Returns an array of references-to-hash; the keys are C<barcode> and
481 The returned items include very overdue items, but not lost ones.
486 #called from request.pl
487 my ($biblionumber)=@_;
489 my $dbh = C4::Context->dbh;
496 push @kohafields, "biblionumber";
497 push @values,$biblionumber;
498 push @relations, " "," \@attr 2=1"; ## selecting wthdrawn less then 1
499 push @and_or, "\@and";
501 my ($count,@results)=ZEBRAsearch_kohafields(\@kohafields,\@values,\@relations,$sort,\@and_or,"","");
502 push @fields,"barcode","itemlost","itemnumber","date_due","wthdrawn","notforloan";
503 my ($biblio,@items)=XMLmarc2koha($dbh,$results[0],"holdings", @fields);
512 my ($dbh, $record, $marcflavour) = @_;
513 my ($mintag, $maxtag);
514 if ($marcflavour eq "MARC21") {
517 } else { # assume unimarc if not marc21
530 foreach my $field ($record->field('5..')) {
531 my $value = $field->as_string();
534 $marcnote = {marcnote => $note,};
535 push @marcnotes, $marcnote;
538 if ($note ne $value) {
539 $note = $note." ".$value;
544 $marcnote = {MARCNOTE => $note};
545 push @marcnotes, $marcnote; #load last tag into array
550 my $marcnotesarray=\@marcnotes;
551 return $marcnotesarray;
555 sub getMARCsubjects {
557 my ($dbh, $record, $marcflavour) = @_;
558 my ($mintag, $maxtag);
559 if ($marcflavour eq "MARC21") {
562 } else { # assume unimarc if not marc21
571 foreach my $field ($record->field('6..')) {
572 my $value = $field->subfield('a');
573 $marcsubjct = {MARCSUBJCT => $value,};
574 push @marcsubjcts, $marcsubjct;
578 my $marcsubjctsarray=\@marcsubjcts;
579 return $marcsubjctsarray;
580 } #end getMARCsubjects
584 ### This code is wrong only works with MARC21
585 my ($dbh, $record, $marcflavour) = @_;
586 my ($mintag, $maxtag);
587 if ($marcflavour eq "MARC21") {
590 } else { # assume unimarc if not marc21
599 foreach my $field ($record->field('856')) {
600 my $value = $field->subfield('u');
601 # my $subfil = $data->[1];
602 if ( $value ne $url) {
603 $marcurl = {MARCURL => $value,};
604 push @marcurls, $marcurl;
610 my $marcurlsarray=\@marcurls;
611 return $marcurlsarray;
617 #pass this a MARC record and it will parse it for display purposes
618 my ($dbh,$intranet,@marcrecords)=@_;
621 my $retrieve_from=C4::Context->preference('retrieve_from');
622 #Build brancnames hash for displaying in OPAC - more user friendly
624 #get branch information.....
626 my $bsth=$dbh->prepare("SELECT branchcode,branchname FROM branches");
628 while (my $bdata=$bsth->fetchrow_hashref){
629 $branches{$bdata->{'branchcode'}}= $bdata->{'branchname'};
632 #Building shelving hash if library has shelves defined like junior section, non-fiction, audio-visual room etc
635 my ($tagfield,$tagsubfield)=MARCfind_marc_from_kohafield("shelf","holdings");
636 my $shelfstatus = $dbh->prepare("select authorised_value from holdings_subfield_structure where tagfield='$tagfield' and tagsubfield='$tagsubfield'");
637 $shelfstatus->execute;
638 my ($authorised_valuecode) = $shelfstatus->fetchrow;
639 if ($authorised_valuecode) {
640 $shelfstatus = $dbh->prepare("select lib,authorised_value from authorised_values where category=? ");
641 $shelfstatus->execute($authorised_valuecode);
642 while (my $lib = $shelfstatus->fetchrow_hashref){
643 $shelves{$lib->{'authorised_value'}} = $lib->{'lib'};
647 foreach my $xmlrecord(@marcrecords){
648 my $xml=XML_xml2hash($xmlrecord);
649 my @kohafields; ## just name those necessary for the result page
650 push @kohafields, "biblionumber","title","author","publishercode","classification","itemtype","copyrightdate", "holdingbranch","date_due","location","shelf","itemcallnumber","notforloan","itemlost","wthdrawn";
651 my ($oldbiblio,@itemrecords) = XMLmarc2koha($dbh,$xml,"",@kohafields);
659 ##Loop for each item field
661 foreach my $item (@itemrecords) {
662 $norequests = 0 unless $item->{'itemnotforloan'};
665 #renaming some fields according to templates
666 $item->{'branchname'}=$branches{$item->{'holdingbranch'}};
667 $item->{'shelves'}=$shelves{$item->{'shelf'}};
668 $status="Lost" if ($item->{'itemlost'}>0);
669 $status="Withdrawn" if ($item->{'wthdrawn'}>0);
670 if ($intranet eq "intranet"){ ## we give full itemcallnumber detail in intranet
671 $status="Due:".format_date($item->{'date_due'}) if ($item->{'date_due'} gt "0000-00-00");
672 $status = $item->{'holdingbranch'}."-".$item->{'shelf'}."[".$item->{'itemcallnumber'}."]" unless defined $status;
674 $status="On Loan" if ($item->{'date_due'} gt "0000-00-00");
675 $status = $item->{'branchname'}."[".$item->{'shelves'}."]" unless defined $status;
681 $oldbiblio->{'noitems'} = $noitems;
682 $oldbiblio->{'norequests'} = $norequests;
683 $oldbiblio->{'even'} = $even;
686 $oldbiblio->{'toggle'}="#ffffcc";
688 $oldbiblio->{'toggle'}="white";
689 } ; ## some forms seems to use toggle
691 $oldbiblio->{'itemcount'} = $counts{'total'};
692 my $totalitemcounts = 0;
693 foreach my $key (keys %counts){
694 if ($key ne 'total'){
695 $totalitemcounts+= $counts{$key};
696 $oldbiblio->{'locationhash'}->{$key}=$counts{$key};
700 my ($locationtext, $locationtextonly, $notavailabletext) = ('','','');
701 foreach (sort keys %{$oldbiblio->{'locationhash'}}) {
703 if ($_ eq 'notavailable') {
704 $notavailabletext="Not available";
705 my $c=$oldbiblio->{'locationhash'}->{$_};
706 $oldbiblio->{'not-available-p'}=$c;
709 my $c=$oldbiblio->{'locationhash'}->{$_};
711 $oldbiblio->{'lost-p'} = $c;
712 } elsif ($_ eq 'Withdrawn') {
713 $oldbiblio->{'withdrawn-p'} = $c;
714 } elsif ($_ =~/\^Due:/) {
716 $oldbiblio->{'on-loan-p'} = $c;
718 $locationtextonly.= $_;
719 $locationtextonly.= " ($c)<br> " if $totalitemcounts > 1;
721 if ($totalitemcounts>1) {
722 $locationtext.=" ($c)<br> ";
726 if ($notavailabletext) {
727 $locationtext.= $notavailabletext;
729 $locationtext=~s/, $//;
731 $oldbiblio->{'location'} = $locationtext;
732 $oldbiblio->{'location-only'} = $locationtextonly;
733 $oldbiblio->{'use-location-flags-p'} = 1;
734 push @results,$oldbiblio;
736 }## For each record received
741 ## return the address of a cover image if defined otherwise the amazon cover images
742 my $record =shift @_;
744 my($phototag,$photosubtag)=MARCfind_marc_from_kohafield("coverphoto","biblios");
746 my $imagetag=$record->field($phototag);
747 my $image=$imagetag->subfield($photosubtag) if $imagetag;
748 return $image if $image;
750 # if there is no image put the amazon cover image adress
751 my($isbntag,$isbnsubtag)=MARCfind_marc_from_kohafield("isbn","biblios");
752 my $isbn=$record->field($isbntag)->subfield($isbnsubtag) if $record->field($isbntag);
753 return "http://images.amazon.com/images/P/".$isbn.".01.MZZZZZZZ.jpg";
758 ($count, $lcount, $nacount, $fcount, $scount, $lostcount,
759 $mending, $transit,$ocount) =
760 &itemcount($env, $biblionumber, $type);
762 Counts the number of items with the given biblionumber, broken down by
767 If C<$type> is not set to C<intra>, lost, very overdue, and withdrawn
768 items will not be counted.
770 C<&itemcount> returns a nine-element list:
772 C<$count> is the total number of items with the given biblionumber.
774 C<$lcount> is the number of items at the Levin branch.
776 C<$nacount> is the number of items that are neither borrowed, lost,
777 nor withdrawn (and are therefore presumably on a shelf somewhere).
779 C<$fcount> is the number of items at the Foxton branch.
781 C<$scount> is the number of items at the Shannon branch.
783 C<$lostcount> is the number of lost and very overdue items.
785 C<$mending> is the number of items at the Mending branch (being
788 C<$transit> is the number of items at the Transit branch (in transit
791 C<$ocount> is the number of items that haven't arrived yet
792 (aqorders.quantity - aqorders.quantityreceived).
800 my ($env,$bibnum,$type)=@_;
801 my $dbh = C4::Context->dbh;
807 my $query="Select * from items where
809 push @kohafield,"biblionumber";
812 my ($total,@result)=ZEBRAsearch_kohafields(\@kohafield,\@value, \@relation,"", \@and_or, 0);## there is only one record no need for $num or $offset
813 my @fields;## extract only the fields required
814 push @fields,"itemnumber","itemlost","wthdrawn","holdingbranch","date_due";
815 my ($biblio,@items)=XMLmarc2koha ($dbh,$result[0],"holdings",\@fields);
825 foreach my $data(@items){
826 if ($type ne "intra"){
827 next if ($data->{itemlost} || $data->{wthdrawn});
828 } ## Probably trying to hide lost item from opac ?
831 ## Now it seems we want to find those which are onloan
834 if ( $data->{date_due} gt "0000-00-00"){
838 ### The rest of this code is hardcoded for Foxtrot Shanon etc. We urgently need a global understanding of these terms--TG
839 if ($data->{'holdingbranch'} eq 'C' || $data->{'holdingbranch'} eq 'LT'){
842 if ($data->{'holdingbranch'} eq 'F' || $data->{'holdingbranch'} eq 'FP'){
845 if ($data->{'holdingbranch'} eq 'S' || $data->{'holdingbranch'} eq 'SP'){
848 if ($data->{'itemlost'} eq '1'){
851 if ($data->{'itemlost'} eq '2'){
854 if ($data->{'holdingbranch'} eq 'FM'){
857 if ($data->{'holdingbranch'} eq 'TR'){
863 my $sth2=$dbh->prepare("Select * from aqorders where biblionumber=?");
864 $sth2->execute($bibnum);
865 if (my $data=$sth2->fetchrow_hashref){
866 $ocount=$data->{'quantity'} - $data->{'quantityreceived'};
870 return ($count,$lcount,$nacount,$fcount,$scount,$lostcount,$mending,$transit,$ocount);
873 END { } # module clean-up code here (global destructor)
882 Koha Developement team <info@koha.org>
883 # New functions to comply with ZEBRA search and new KOHA 3 API added 2006 Tumer Garip tgarip@neu.edu.tr