3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
28 use MARC::File::USMARC;
30 # use Smart::Comments;
33 use vars qw($VERSION @ISA @EXPORT);
35 # set the version for version checking
36 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
37 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
42 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
43 # as the old-style API and the NEW one are the only public functions.
46 &newbiblio &newbiblioitem
47 &newsubject &newsubtitle &newitems
49 &modbiblio &checkitems &modbibitem
50 &modsubtitle &modsubject &modaddauthor &moditem
52 &delitem &deletebiblioitem &delbiblio
54 &getbiblio &bibdata &bibitems &bibitemdata
55 &barcodes &ItemInfo &itemdata &itemissues &itemcount
56 &getsubject &getaddauthor &getsubtitle
57 &getwebbiblioitems &getwebsites
58 &getbiblioitembybiblionumber
59 &getbiblioitem &getitemsbybiblioitem
61 &MARCfind_marc_from_kohafield
62 &MARCfind_frameworkcode
63 &find_biblioitemnumber
66 &NEWnewbiblio &NEWnewitem
67 &NEWmodbiblio &NEWmoditem
68 &NEWdelbiblio &NEWdelitem
69 &NEWmodbiblioframework
71 &MARCkoha2marcBiblio &MARCmarc2koha
72 &MARCkoha2marcItem &MARChtml2marc &MARChtml2xml
73 &MARCgetbiblio &MARCgetitem
80 &z3950_extended_services
83 &get_item_from_barcode
84 &MARCfind_MARCbibid_from_oldbiblionumber
88 get_biblioiteminfos_of
93 C4::Biblio - Acquisitions, Catalog Management Functions
97 ( lot of changes for Koha 3.X)
99 Koha 1.2 and previous versions used a specific API to manage biblios. This API uses old-DB style parameters.
100 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors,
101 bibliosubject and bibliosubtitle where applicable).
103 In Koha 2.X, we introduced a MARC-DB.
105 In Koha 3.X, we removed this MARC-DB for search as we wanted to use Zebra as search system.
107 So in Koha 3.X, saving a record means :
109 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items information.
110 - storing the "decoded information" in biblio/biblioitems/items as previously.
111 - using zebra to manage search & indexing on the MARC data.
113 In Koha, there is a systempreference for "MARC=ON" or "MARC=OFF" :
115 * MARC=ON : when MARC=ON, Koha uses a MARC::Record object (in sub parameters). Saving information in the DB means :
117 - transform the MARC record into a hash
118 - add the raw MARC record into the hash
119 - store them & update Zebra
121 * MARC=OFF : when MARC=OFF, Koha uses a hash object (in sub parameters). Saving information in the DB means :
123 - transform the hash into a MARC record
124 - add the raw marc record into the hash
125 - store them & update zebra
127 That's why we need 3 types of subs :
131 all I<subs beginning by REAL> do the effective storage of information (with a hash, one field of the hash being the raw marc record). Those subs also update the record in Zebra. REAL subs should be only for internal use (called by NEW or "something else" subs).
133 =head2 NEWxxx related subs
137 all I<subs beginning by NEW> use MARC::Record as parameters. It's the API that MUST be used in the MARC acquisition system. They just create the hash, add it the raw marc record. Then, they call REALxxx sub.
139 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. They sometimes require another parameter.
143 =head2 something_elsexxx related subs
147 all I<subs beginning by seomething else> are the old-style API. They use a hash as parameter, transform the hash into a -small- marc record, and call REAL subs.
149 all subs require/use $dbh as 1st parameter and a hash as 2nd parameter.
155 =head2 z3950_extended_services
157 z3950_extended_services($serviceType,$serviceOptions,$record);
159 z3950_extended_services is used to handle all interactions with Zebra's extended serices package.
161 C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate
163 C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain:
165 action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
169 recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
170 syntax => the record syntax (transfer syntax)
171 databaseName = Database from connection object
173 To set serviceOptions, call set_service_options($serviceType)
175 C<$record> the record, if one is needed for the service type
177 A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
180 sub z3950_extended_services {
181 my ($serviceType,$serviceOptions,$record) = @_;
183 my $Zconn = C4::Context->Zconn;
184 # create a new package object
185 my $Zpackage = $Zconn->package();
188 $Zpackage->option(action => $serviceOptions->{'action'});
190 if ($serviceOptions->{'databaseName'}) {
191 $Zpackage->option(databaseName => $serviceOptions->{'databaseName'});
193 if ($serviceOptions->{'recordIdNumber'}) {
194 $Zpackage->option(recordIdNumber => $serviceOptions->{'recordIdNumber'});
196 if ($serviceOptions->{'recordIdOpaque'}) {
197 $Zpackage->option(recordIdOpaque => $serviceOptions->{'recordIdOpaque'});
200 # this is an ILL request (Zebra doesn't support it)
201 #if ($serviceType eq 'itemorder') {
202 # $Zpackage->option('contact-name' => $serviceOptions->{'contact-name'});
203 # $Zpackage->option('contact-phone' => $serviceOptions->{'contact-phone'});
204 # $Zpackage->option('contact-email' => $serviceOptions->{'contact-email'});
205 # $Zpackage->option('itemorder-item' => $serviceOptions->{'itemorder-item'});
209 my $xmlrecord = marc2xml($record);
210 $Zpackage->option(record => $xmlrecord);
211 if ($serviceOptions->{'syntax'}) {
212 $Zpackage->option(syntax => $serviceOptions->{'syntax'});
216 # send the request, handle any exception encountered
217 eval { $Zpackage->send($serviceType) };
218 if ($@ && $@->isa("ZOOM::Exception")) {
219 print "Oops! ", $@->message(), "\n";
222 # free up package resources
223 $Zpackage->destroy();
226 =head2 set_service_options
228 my $serviceOptions = set_service_options($serviceType);
230 C<$serviceType> itemorder,create,drop,commit,update,xmlupdate
232 Currently, we only support 'create', 'commit', and 'update'. 'drop' support will be added as soon as Zebra supports it.
236 sub set_service_options {
237 my ($serviceType,$action,$recordId) = @_;
240 if ($serviceType eq 'update') {
242 $serviceOptions->{ 'action' } = $action;
244 $serviceOptions->{ 'action' } = 'specialUpdate';
247 $serviceOptions->{'recordIdNumber'} = $recordId;
250 # FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change
251 # $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml
254 if ($serviceType eq 'commit') {
258 if ($serviceType eq 'create') {
261 if ($serviceType eq 'drop') {
262 die "ERROR: 'drop' not currently supported (by Zebra)";
266 return $serviceOptions;
271 my $xmlrecord = marc2xml($record);
273 Convert from MARC to XML. Note that MARC::File::XML will automatically encode from MARC-8 to UTF-8 as of version .8
275 C<$record> a MARC record
282 eval { $xmlrecord=$record->as_xml_record() };
283 #TODO: better error handling here
285 warn "ERROR: I suspect a badly formatted MARC record";
290 =head2 MARCgettagslib
292 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
296 2nd param is 1 for liblibrarian and 0 for libopac
297 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
299 returns a hash with all values for all fields and subfields for a given MARC framework :
300 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
302 ->{mandatory} = $mandatory;
303 ->{repeatable} = $repeatable;
304 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
306 ->{mandatory} = $mandatory;
307 ->{repeatable} = $repeatable;
308 ->{authorised_value} = $authorised_value;
309 ->{authtypecode} = $authtypecode;
310 ->{value_builder} = $value_builder;
311 ->{kohafield} = $kohafield;
312 ->{seealso} = $seealso;
313 ->{hidden} = $hidden;
322 # old subroutine to provide backwards compatibility.
323 # opac-detail breaks without this. Can be removed once opac-detail is fixed
324 sub MARCfind_MARCbibid_from_oldbiblionumber {
325 my ($biblionumber)=@_;
326 return ($biblionumber);
331 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
332 $frameworkcode = "" unless $frameworkcode;
333 $forlibrarian = 1 unless $forlibrarian;
335 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
337 # check that framework exists
340 "select count(*) from marc_tag_structure where frameworkcode=?");
341 $sth->execute($frameworkcode);
342 my ($total) = $sth->fetchrow;
343 $frameworkcode = "" unless ( $total > 0 );
346 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
348 $sth->execute($frameworkcode);
349 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
351 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
352 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
353 $res->{$tag}->{tab} = ""; # XXX
354 $res->{$tag}->{mandatory} = $mandatory;
355 $res->{$tag}->{repeatable} = $repeatable;
360 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link from marc_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
362 $sth->execute($frameworkcode);
365 my $authorised_value;
375 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
376 $mandatory, $repeatable, $authorised_value, $authtypecode,
377 $value_builder, $kohafield, $seealso, $hidden,
382 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
383 $res->{$tag}->{$subfield}->{tab} = $tab;
384 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
385 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
386 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
387 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
388 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
389 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
390 $res->{$tag}->{$subfield}->{seealso} = $seealso;
391 $res->{$tag}->{$subfield}->{hidden} = $hidden;
392 $res->{$tag}->{$subfield}->{isurl} = $isurl;
393 $res->{$tag}->{$subfield}->{link} = $link;
398 =head2 MARCfind_marc_from_kohafield
400 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
404 finds MARC tag and subfield for a given kohafield
405 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
411 sub MARCfind_marc_from_kohafield {
412 my ( $dbh, $kohafield,$frameworkcode ) = @_;
413 return 0, 0 unless $kohafield;
414 $frameworkcode='' unless $frameworkcode;
415 my $relations = C4::Context->marcfromkohafield;
416 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
421 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
425 Returns a MARC::Record for the biblio $biblionumber.
431 # Returns MARC::Record of the biblio passed in parameter.
432 my ( $dbh, $biblionumber ) = @_;
433 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
434 $sth->execute($biblionumber);
435 my ($marc) = $sth->fetchrow;
436 my $record = MARC::Record::new_from_usmarc($marc);
442 $XML = &XMLgetbiblio($dbh,$biblionumber);
446 Returns a raw XML for the biblio $biblionumber.
452 # Returns MARC::Record of the biblio passed in parameter.
453 my ( $dbh, $biblionumber ) = @_;
454 my $sth = $dbh->prepare('select marcxml,marc from biblioitems where biblionumber=?');
455 $sth->execute($biblionumber);
456 my ($XML,$marc) = $sth->fetchrow;
457 # my $record =MARC::Record::new_from_usmarc($marc);
458 # warn "MARC : \n*-************************\n".$record->as_xml."\n*-************************\n";
464 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
468 Returns a MARC::Record with all items of biblio # $biblionumber
476 my ( $dbh, $biblionumber, $itemnumber ) = @_;
477 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
478 # get the complete MARC record
479 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
480 $sth->execute($biblionumber);
481 my ($rawmarc) = $sth->fetchrow;
482 my $record = C4::Search::get_record($biblionumber);
483 # warn "ITEMRECORD".$record->as_formatted;
484 # now, find the relevant itemnumber
485 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
486 # prepare the new item record
487 my $itemrecord = MARC::Record->new();
488 # parse all fields fields from the complete record
489 foreach ($record->field($itemnumberfield)) {
490 # when the item field is found, save it
491 # warn "Itenumberfield = $itemnumberfield";
492 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
493 # warn "Inside if subfield=$itemnumbersubfield";
494 $itemrecord->append_fields($_);
496 warn "No match subfield=$itemnumbersubfield and
497 itemnumber=$itemnumber";
500 # warn "ITEMS".$itemrecord->as_formatted;
505 ##Changes only field or subfield from the holdings fields of MARC record used for branch transfers or onloan flag -TG
508 sub MARCmoditemonefield{
509 my ($dbh,$biblionumber,$itemnumber,$itemfield,$newvalue)=@_;
511 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
512 # get the complete MARC record
513 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
514 $sth->execute($biblionumber);
515 my ($rawmarc) = $sth->fetchrow;
516 my $bibliorecord=MARC::File::USMARC::decode($rawmarc);
517 # now, find the relevant itemnumber
518 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
519 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,$itemfield,$frameworkcode);
521 # parse all fields fields from the complete record
522 foreach ($bibliorecord->field($itemnumberfield)) {
523 # when the item field is found, update it
524 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
525 $_->update($tagsubfield =>$newvalue);
529 # save the record into biblioitem
530 $dbh->do('lock tables biblioitems WRITE');
531 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
532 $sth->execute($bibliorecord->as_usmarc(),$bibliorecord->as_xml_record(),$biblionumber);
533 z3950_extended_services('update',set_service_options('update'),$bibliorecord);
534 z3950_extended_services('commit');
535 $dbh->do('unlock tables');
538 =head2 find_biblioitemnumber
540 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
544 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
545 This sub is useless when MARC=OFF
550 sub find_biblioitemnumber {
551 my ( $dbh, $biblionumber ) = @_;
552 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
553 $sth->execute($biblionumber);
554 my ($biblioitemnumber) = $sth->fetchrow;
555 return $biblioitemnumber;
558 =head2 MARCfind_frameworkcode
560 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
564 returns the framework of a given biblio
570 sub MARCfind_frameworkcode {
571 my ( $dbh, $biblionumber ) = @_;
572 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
573 $sth->execute($biblionumber);
574 my ($frameworkcode) = $sth->fetchrow;
575 return $frameworkcode;
578 =head2 MARCkoha2marcBiblio
580 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
584 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
585 all entries of the hash are transformed into their matching MARC field/subfield.
591 sub MARCkoha2marcBiblio {
593 # this function builds partial MARC::Record from the old koha-DB fields
594 my ( $dbh, $bibliohash ) = @_;
595 # we don't have biblio entries in the hash, so we add them first
596 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
597 $sth->execute($bibliohash->{biblionumber});
598 my $biblio = $sth->fetchrow_hashref;
599 foreach (keys %$biblio) {
600 $bibliohash->{$_}=$biblio->{$_};
602 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
603 my $record = MARC::Record->new();
604 foreach ( keys %$bibliohash ) {
605 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
606 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
609 # other fields => additional authors, subjects, subtitles
610 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
611 $sth2->execute($bibliohash->{biblionumber});
612 while ( my $row = $sth2->fetchrow_hashref ) {
613 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
615 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
616 $sth2->execute($bibliohash->{biblionumber});
617 while ( my $row = $sth2->fetchrow_hashref ) {
618 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
620 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
621 $sth2->execute($bibliohash->{biblionumber});
622 while ( my $row = $sth2->fetchrow_hashref ) {
623 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
629 =head2 MARCkoha2marcItem
631 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
633 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
634 all entries of the hash are transformed into their matching MARC field/subfield.
642 sub MARCkoha2marcItem {
644 # this function builds partial MARC::Record from the old koha-DB fields
645 my ( $dbh, $item ) = @_;
647 # my $dbh=&C4Connect;
648 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
649 my $record = MARC::Record->new();
651 foreach( keys %$item ) {
653 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
660 =head2 MARCkoha2marcOnefield
664 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
670 sub MARCkoha2marcOnefield {
671 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
674 $sth->execute($frameworkcode,$kohafieldname);
675 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
676 if ( $record->field($tagfield) ) {
677 my $tag = $record->field($tagfield);
679 $tag->add_subfields( $tagsubfield, $value );
680 $record->delete_field($tag);
681 $record->add_fields($tag);
685 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
692 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
694 transforms the parameters (coming from HTML form) into a MARC::File::XML
695 object. parameters with r are references to arrays
699 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
701 my $xml= MARC::File::XML::header();
706 for (my $i=0;$i<=@$tags;$i++){
707 @$values[$i] =~ s/&/&/g;
708 @$values[$i] =~ s/</</g;
709 @$values[$i] =~ s/>/>/g;
710 @$values[$i] =~ s/"/"/g;
711 @$values[$i] =~ s/'/'/g;
713 if ((@$tags[$i] ne $prevtag)){
714 $j++ unless (@$tags[$i] eq "");
715 #warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
717 $xml.="</datafield>\n";
718 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
719 my $ind1 = substr(@$indicator[$j],0,1);
720 my $ind2 = substr(@$indicator[$j],1,1);
721 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
722 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
728 if (@$values[$i] ne "") {
730 if (@$tags[$i] eq "000") {
731 $xml.="<leader>@$values[$i]</leader>\n";
733 # rest of the fixed fields
734 } elsif (@$tags[$i] < 10) {
735 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
738 my $ind1 = substr(@$indicator[$j],0,1);
739 my $ind2 = substr(@$indicator[$j],1,1);
740 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
741 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
746 } else { # @$tags[$i] eq $prevtag
747 if (@$values[$i] eq "") {
751 my $ind1 = substr(@$indicator[$j],0,1);
752 my $ind2 = substr(@$indicator[$j],1,1);
753 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
756 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
759 $prevtag = @$tags[$i];
761 $xml.= MARC::File::XML::footer();
768 $hash = &MARCmarc2koha($dbh,$MARCRecord);
772 builds a hash with old-db datas from a MARC::Record
779 my ($dbh,$record,$frameworkcode) = @_;
780 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
782 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
785 while (($field)=$sth2->fetchrow) {
786 # warn "biblio.".$field;
787 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
789 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
791 while (($field)=$sth2->fetchrow) {
792 if ($field eq 'notes') { $field = 'bnotes'; }
793 # warn "biblioitems".$field;
794 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
796 $sth2=$dbh->prepare("SHOW COLUMNS from items");
798 while (($field)=$sth2->fetchrow) {
799 # warn "items".$field;
800 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
802 # additional authors : specific
803 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
804 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
805 # modify copyrightdate to keep only the 1st year found
806 my $temp = $result->{'copyrightdate'};
808 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
810 $result->{'copyrightdate'} = $1;
811 } else { # if no cYYYY, get the 1st date.
812 $temp =~ m/(\d\d\d\d)/;
813 $result->{'copyrightdate'} = $1;
816 # modify publicationyear to keep only the 1st year found
817 $temp = $result->{'publicationyear'};
818 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
820 $result->{'publicationyear'} = $1;
821 } else { # if no cYYYY, get the 1st date.
822 $temp =~ m/(\d\d\d\d)/;
823 $result->{'publicationyear'} = $1;
828 sub MARCmarc2kohaOneField {
830 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
831 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
832 # warn "kohatable / $kohafield / $result / ";
836 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
837 foreach my $field ( $record->field($tagfield) ) {
838 if ($field->tag()<10) {
839 if ($result->{$kohafield}) {
840 # Reverse array filled with elements from repeated subfields
841 # from first to last to avoid last to first concatenation of
842 # elements in Koha DB. -- thd.
843 $result->{$kohafield} .= " | ".reverse($field->data());
845 $result->{$kohafield} = $field->data();
848 if ( $field->subfields ) {
849 my @subfields = $field->subfields();
850 foreach my $subfieldcount ( 0 .. $#subfields ) {
851 if ($subfields[$subfieldcount][0] eq $subfield) {
852 if ( $result->{$kohafield} ) {
853 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
856 $result->{$kohafield} = $subfields[$subfieldcount][1];
863 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
869 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
873 creates a biblio from a MARC::Record.
880 my ( $dbh,$record,$frameworkcode ) = @_;
882 my $biblioitemnumber;
883 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
884 $olddata->{frameworkcode} = $frameworkcode;
885 $biblionumber = REALnewbiblio( $dbh, $olddata );
886 $olddata->{biblionumber} = $biblionumber;
887 # add biblionumber into the MARC record (it's the ID for zebra)
888 my ( $tagfield, $tagsubfield ) =
889 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
893 $newfield = MARC::Field->new(
894 $tagfield, $biblionumber,
897 $newfield = MARC::Field->new(
898 $tagfield, '', '', "$tagsubfield" => $biblionumber,
901 # drop old field (just in case it already exist and create new one...
902 my $old_field = $record->field($tagfield);
903 $record->delete_field($old_field);
904 $record->add_fields($newfield);
905 #Change MARC Leader to UTF-8 incase user did not set it.New M::F::XML is sensitive to this
906 $record->encoding('UTF-8');
907 #create the marc entry, that stores the rax marc record in Koha 3.0
908 $olddata->{marc} = $record->as_usmarc();
909 $olddata->{marcxml} = $record->as_xml_record();
910 # and create biblioitem, that's all folks !
911 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
913 # search subtiles, addiauthors and subjects
914 ( $tagfield, $tagsubfield ) =
915 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
916 my @addiauthfields = $record->field($tagfield);
917 foreach my $addiauthfield (@addiauthfields) {
918 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
919 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
920 REALmodaddauthor( $dbh, $biblionumber,
921 $addiauthsubfields[$subfieldcount] );
924 ( $tagfield, $tagsubfield ) =
925 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
926 my @subtitlefields = $record->field($tagfield);
927 foreach my $subtitlefield (@subtitlefields) {
928 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
929 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
930 REALnewsubtitle( $dbh, $biblionumber,
931 $subtitlesubfields[$subfieldcount] );
934 ( $tagfield, $tagsubfield ) =
935 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
936 my @subj = $record->field($tagfield);
938 foreach my $subject (@subj) {
939 my @subjsubfield = $subject->subfield($tagsubfield);
940 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
941 push @subjects, $subjsubfield[$subfieldcount];
944 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
945 return ( $biblionumber, $biblioitemnumber );
948 =head2 NEWmodbilbioframework
950 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
954 modify the framework of a biblio
960 sub NEWmodbiblioframework {
961 my ($dbh,$biblionumber,$frameworkcode) =@_;
962 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
963 $sth->execute($frameworkcode,$biblionumber);
969 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
973 modify a biblio (MARC=ON)
980 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
981 $frameworkcode="" unless $frameworkcode;
982 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
983 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
985 $oldbiblio->{frameworkcode} = $frameworkcode;
986 #create the marc entry, that stores the rax marc record in Koha 3.0
987 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
988 $oldbiblio->{marc} = $record->as_usmarc();
989 $oldbiblio->{marcxml} = $record->as_xml_record();
990 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
991 REALmodbiblio($dbh,$oldbiblio);
992 REALmodbiblioitem($dbh,$oldbiblio);
993 # now, modify addi authors, subject, addititles.
994 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
995 my @addiauthfields = $record->field($tagfield);
996 foreach my $addiauthfield (@addiauthfields) {
997 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
998 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
999 foreach my $subfieldcount (0..$#addiauthsubfields) {
1000 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
1003 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
1004 my @subtitlefields = $record->field($tagfield);
1005 foreach my $subtitlefield (@subtitlefields) {
1006 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1007 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
1009 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
1010 foreach my $subfieldcount (0..$#subtitlesubfields) {
1011 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1012 REALnewsubtitle($dbh,$biblionumber,$subtit);
1016 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1017 my @subj = $record->field($tagfield);
1019 foreach my $subject (@subj) {
1020 my @subjsubfield = $subject->subfield($tagsubfield);
1021 foreach my $subfieldcount (0..$#subjsubfield) {
1022 push @subjects,$subjsubfield[$subfieldcount];
1025 REALmodsubject($dbh,$biblionumber,1,@subjects);
1029 =head2 NEWmodbilbioframework
1031 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1042 my ( $dbh, $bibid ) = @_;
1043 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1044 &REALdelbiblio( $dbh, $bibid );
1047 "select biblioitemnumber from biblioitems where biblionumber=?");
1048 $sth->execute($bibid);
1049 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1050 REALdelbiblioitem( $dbh, $biblioitemnumber );
1052 # &MARCdelbiblio( $dbh, $bibid, 0 );
1054 warn "heres the bibid $bibid";
1055 # my $record = C4::Search::get_record($bibid);
1056 my $record = C4::Search::get_xml_record($bibid);
1057 # z3950_extended_services('update',set_service_options('update'),$record);
1058 warn "heres the record to delete $bibid";
1059 my $Zconn = C4::Context->Zconn;
1060 my $p = $Zconn->package();
1061 $p->option(action => "recordDelete");
1062 $p->option(record => $record);
1065 # z3950_extended_services('update',set_service_options('update','recordDelete',$record));
1066 z3950_extended_services('commit');
1071 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1075 creates an item from a MARC::Record
1082 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1083 warn "here is the $biblioitemnumber";
1084 # add item in old-DB
1085 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1086 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1087 # needs old biblionumber and biblioitemnumber
1088 $item->{'biblionumber'} = $biblionumber;
1089 $item->{'biblioitemnumber'}=$biblioitemnumber;
1090 $item->{marc} = $record->as_usmarc();
1091 #warn $item->{marc};
1092 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1099 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1110 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1112 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1113 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1115 $olditem->{marc} = $record->as_usmarc();
1116 $olditem->{biblionumber} = $biblionumber;
1117 $olditem->{biblioitemnumber} = $biblioitemnumber;
1119 REALmoditem( $dbh, $olditem );
1125 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1136 my ( $dbh, $bibid, $itemnumber ) = @_;
1137 &REALdelitem( $dbh, $itemnumber );
1138 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1139 # we must now delete the item data from zebra
1143 =head2 REALnewbiblio
1145 $biblionumber = REALnewbiblio($dbh,$biblio);
1149 adds a record in biblio table. Datas are in the hash $biblio.
1156 my ( $dbh, $biblio ) = @_;
1158 $dbh->do('lock tables biblio WRITE');
1159 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1161 my $data = $sth->fetchrow_arrayref;
1162 my $bibnum = $$data[0] + 1;
1165 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1168 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1169 serial=?, seriestitle=?, notes=?, abstract=?,
1173 $bibnum, $biblio->{'title'},
1174 $biblio->{'author'}, $biblio->{'copyrightdate'},
1175 $biblio->{'serial'}, $biblio->{'seriestitle'},
1176 $biblio->{'notes'}, $biblio->{'abstract'},
1177 $biblio->{'unititle'}
1181 $dbh->do('unlock tables');
1185 =head2 REALmodbiblio
1187 $biblionumber = REALmodbiblio($dbh,$biblio);
1191 modify a record in biblio table. Datas are in the hash $biblio.
1198 my ( $dbh, $biblio ) = @_;
1199 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1200 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1201 where biblionumber = ?"
1204 $biblio->{'title'}, $biblio->{'author'},
1205 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1206 $biblio->{'seriestitle'}, $biblio->{'serial'},
1207 $biblio->{'unititle'}, $biblio->{'notes'},
1208 $biblio->{frameworkcode},
1209 $biblio->{'biblionumber'}
1212 return ( $biblio->{'biblionumber'} );
1215 =head2 REALmodsubtitle
1217 REALmodsubtitle($dbh,$bibnum,$subtitle);
1221 modify subtitles in bibliosubtitle table.
1227 sub REALmodsubtitle {
1228 my ( $dbh, $bibnum, $subtitle ) = @_;
1231 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1232 $sth->execute( $subtitle, $bibnum );
1236 =head2 REALmodaddauthor
1238 REALmodaddauthor($dbh,$bibnum,$author);
1242 adds or modify additional authors
1243 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1249 sub REALmodaddauthor {
1250 my ( $dbh, $bibnum, @authors ) = @_;
1252 # my $dbh = C4Connect;
1254 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1256 $sth->execute($bibnum);
1258 foreach my $author (@authors) {
1259 if ( $author ne '' ) {
1262 "Insert into additionalauthors set author = ?, biblionumber = ?"
1265 $sth->execute( $author, $bibnum );
1270 } # sub modaddauthor
1272 =head2 REALmodsubject
1274 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1278 modify/adds subjects
1283 sub REALmodsubject {
1284 my ( $dbh, $bibnum, $force, @subject ) = @_;
1286 # my $dbh = C4Connect;
1287 my $count = @subject;
1289 for ( my $i = 0 ; $i < $count ; $i++ ) {
1290 $subject[$i] =~ s/^ //g;
1291 $subject[$i] =~ s/ $//g;
1294 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1296 $sth->execute( $subject[$i] );
1298 if ( my $data = $sth->fetchrow_hashref ) {
1301 if ( $force eq $subject[$i] || $force == 1 ) {
1303 # subject not in aut, chosen to force anway
1304 # so insert into cataloguentry so its in auth file
1307 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1310 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1315 "$subject[$i]\n does not exist in the subject authority file";
1318 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1320 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1322 while ( my $data = $sth2->fetchrow_hashref ) {
1323 $error .= "<br>$data->{'catalogueentry'}";
1332 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1333 $sth->execute($bibnum);
1337 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1339 foreach $query (@subject) {
1340 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1349 =head2 REALmodbiblioitem
1351 REALmodbiblioitem($dbh, $biblioitem);
1360 sub REALmodbiblioitem {
1361 my ( $dbh, $biblioitem ) = @_;
1364 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1365 itemtype=?, url=?, isbn=?, issn=?,
1366 publishercode=?, publicationyear=?, classification=?, dewey=?,
1367 subclass=?, illus=?, pages=?, volumeddesc=?,
1368 notes=?, size=?, place=?, marc=?,
1370 where biblioitemnumber=?");
1371 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1372 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1373 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1374 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1375 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1376 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1378 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1380 z3950_extended_services('update',set_service_options('update'),$record);
1381 z3950_extended_services('commit');
1384 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1387 =head2 REALnewbiblioitem
1389 REALnewbiblioitem($dbh,$biblioitem);
1393 adds a biblioitem ($biblioitem is a hash with the values)
1399 sub REALnewbiblioitem {
1400 my ( $dbh, $biblioitem ) = @_;
1402 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1403 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1405 my $biblioitemnumber;
1408 $data = $sth->fetchrow_arrayref;
1409 $biblioitemnumber = $$data[0] + 1;
1411 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1412 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1413 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1414 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1415 my $field=$record->field($biblioitemnumberfield);
1416 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1417 $biblioitem->{marc} = $record->as_usmarc();
1418 $biblioitem->{marcxml} = $record->as_xml_record();
1420 $sth = $dbh->prepare( "insert into biblioitems set
1421 biblioitemnumber = ?, biblionumber = ?,
1422 volume = ?, number = ?,
1423 classification = ?, itemtype = ?,
1425 issn = ?, dewey = ?,
1426 subclass = ?, publicationyear = ?,
1427 publishercode = ?, volumedate = ?,
1428 volumeddesc = ?, illus = ?,
1429 pages = ?, notes = ?,
1431 marc = ?, place = ?,
1435 $biblioitemnumber, $biblioitem->{'biblionumber'},
1436 $biblioitem->{'volume'}, $biblioitem->{'number'},
1437 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1438 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1439 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1440 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1441 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1442 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1443 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1444 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1445 $biblioitem->{'marc'}, $biblioitem->{'place'},
1446 $biblioitem->{marcxml},
1448 $dbh->do("unlock tables");
1449 z3950_extended_services('update',set_service_options('update'),$record);
1450 z3950_extended_services('commit');
1451 return ($biblioitemnumber);
1454 =head2 REALnewsubtitle
1456 REALnewsubtitle($dbh,$bibnum,$subtitle);
1460 create a new subtitle
1465 sub REALnewsubtitle {
1466 my ( $dbh, $bibnum, $subtitle ) = @_;
1469 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1470 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1476 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1480 create a item. $item is a hash and $barcode the barcode.
1487 my ( $dbh, $item, $barcode ) = @_;
1489 # warn "OLDNEWITEMS";
1491 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1492 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1497 $data = $sth->fetchrow_hashref;
1498 $itemnumber = $data->{'max(itemnumber)'} + 1;
1500 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1501 if ( $item->{'loan'} ) {
1502 $item->{'notforloan'} = $item->{'loan'};
1504 # $item->{'biblioitemnumber'} = 1;
1505 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1506 if ( $item->{'dateaccessioned'} ) {
1507 $sth = $dbh->prepare( "Insert into items set
1508 itemnumber = ?, biblionumber = ?,
1509 multivolumepart = ?,
1510 biblioitemnumber = ?, barcode = ?,
1511 booksellerid = ?, dateaccessioned = ?,
1512 homebranch = ?, holdingbranch = ?,
1513 price = ?, replacementprice = ?,
1514 replacementpricedate = NOW(), datelastseen = NOW(),
1515 multivolume = ?, stack = ?,
1516 itemlost = ?, wthdrawn = ?,
1517 paidfor = ?, itemnotes = ?,
1518 itemcallnumber =?, notforloan = ?,
1523 $itemnumber, $item->{'biblionumber'},
1524 $item->{'multivolumepart'},
1525 $item->{'biblioitemnumber'},$item->{barcode},
1526 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1527 $item->{'homebranch'}, $item->{'holdingbranch'},
1528 $item->{'price'}, $item->{'replacementprice'},
1529 $item->{multivolume}, $item->{stack},
1530 $item->{itemlost}, $item->{wthdrawn},
1531 $item->{paidfor}, $item->{'itemnotes'},
1532 $item->{'itemcallnumber'}, $item->{'notforloan'},
1535 if ( defined $sth->errstr ) {
1536 $error .= $sth->errstr;
1540 $sth = $dbh->prepare( "Insert into items set
1541 itemnumber = ?, biblionumber = ?,
1542 multivolumepart = ?,
1543 biblioitemnumber = ?, barcode = ?,
1544 booksellerid = ?, dateaccessioned = NOW(),
1545 homebranch = ?, holdingbranch = ?,
1546 price = ?, replacementprice = ?,
1547 replacementpricedate = NOW(), datelastseen = NOW(),
1548 multivolume = ?, stack = ?,
1549 itemlost = ?, wthdrawn = ?,
1550 paidfor = ?, itemnotes = ?,
1551 itemcallnumber =?, notforloan = ?,
1556 $itemnumber, $item->{'biblionumber'},
1557 $item->{'multivolumepart'},
1558 $item->{'biblioitemnumber'},$item->{barcode},
1559 $item->{'booksellerid'},
1560 $item->{'homebranch'}, $item->{'holdingbranch'},
1561 $item->{'price'}, $item->{'replacementprice'},
1562 $item->{multivolume}, $item->{stack},
1563 $item->{itemlost}, $item->{wthdrawn},
1564 $item->{paidfor}, $item->{'itemnotes'},
1565 $item->{'itemcallnumber'}, $item->{'notforloan'},
1568 if ( defined $sth->errstr ) {
1569 $error .= $sth->errstr;
1572 # item stored, now, deal with the marc part...
1573 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1574 where biblio.biblionumber=biblioitems.biblionumber and
1575 biblio.biblionumber=?");
1576 $sth->execute($item->{biblionumber});
1577 if ( defined $sth->errstr ) {
1578 $error .= $sth->errstr;
1580 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1581 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1582 my $record = MARC::File::USMARC::decode($rawmarc);
1583 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1584 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1585 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1587 #warn $itemnumberfield;
1588 #warn $itemrecord->field($itemnumberfield);
1589 my $itemfield = $itemrecord->field($itemnumberfield);
1590 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1591 $record->insert_grouped_field($itemfield);
1592 # save the record into biblioitem
1593 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1594 $sth->execute($record->as_usmarc(),$record->as_xml_record(),$item->{biblionumber});
1595 if ( defined $sth->errstr ) {
1596 $error .= $sth->errstr;
1598 z3950_extended_services('update',set_service_options('update'),$record);
1599 z3950_extended_services('commit');
1600 $dbh->do('unlock tables');
1601 return ( $itemnumber, $error );
1604 =head2 REALmoditem($dbh,$item);
1615 my ( $dbh, $item ) = @_;
1616 $item->{'bibitemnum'} = 1;
1618 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1619 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1620 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1622 $item->{'barcode'}, $item->{'itemnotes'},
1623 $item->{'itemcallnumber'}, $item->{'notforloan'},
1624 $item->{'location'}, $item->{multivolumepart},
1625 $item->{multivolume}, $item->{stack},
1628 if ( $item->{'lost'} ne '' ) {
1629 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1630 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1631 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1633 $item->{'bibitemnum'}, $item->{'barcode'},
1634 $item->{'itemnotes'}, $item->{'homebranch'},
1635 $item->{'lost'}, $item->{'wthdrawn'},
1636 $item->{'itemcallnumber'}, $item->{'notforloan'},
1637 $item->{'location'}, $item->{multivolumepart},
1638 $item->{multivolume}, $item->{stack},
1641 if ($item->{homebranch}) {
1642 $query.=",homebranch=?";
1643 push @bind, $item->{homebranch};
1645 if ($item->{holdingbranch}) {
1646 $query.=",holdingbranch=?";
1647 push @bind, $item->{holdingbranch};
1650 $query.=" where itemnumber=?";
1651 push @bind,$item->{'itemnum'};
1652 if ( $item->{'replacement'} ne '' ) {
1653 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1655 my $sth = $dbh->prepare($query);
1656 $sth->execute(@bind);
1658 # item stored, now, deal with the marc part...
1659 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1660 where biblio.biblionumber=biblioitems.biblionumber and
1661 biblio.biblionumber=? and
1662 biblioitems.biblioitemnumber=?");
1663 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1664 if ( defined $sth->errstr ) {
1665 $error .= $sth->errstr;
1667 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1668 # warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1669 # my $record = MARC::File::USMARC::decode($rawmarc);
1670 my $record=C4::Search::get_record($item->{biblionumber});
1672 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1673 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1674 # prepare the new item record
1675 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1676 my $itemfield = $itemrecord->field($itemnumberfield);
1678 # $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1679 # parse all fields fields from the complete record
1680 foreach ($record->field($itemnumberfield)) {
1681 # when the previous field is found, replace by the new one
1682 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1683 $_->replace_with($itemfield);
1686 my $temptest = $_->subfield($itemnumbersubfield);
1687 warn " failed itemnum is $item->{itemnum} and value in record is $temptest";
1690 # $record->insert_grouped_field($itemfield);
1691 # save the record into biblioitem
1692 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1693 $sth->execute($record->as_usmarc(),$record->as_xml_record(),$item->{biblionumber},$item->{biblioitemnumber});
1694 z3950_extended_services('update',set_service_options('update'),$record);
1695 z3950_extended_services('commit');
1696 if ( defined $sth->errstr ) {
1697 $error .= $sth->errstr;
1699 $dbh->do('unlock tables');
1703 =head2 REALdelitem($dbh,$itemnum);
1714 my ( $dbh, $itemnum ) = @_;
1716 # my $dbh=C4Connect;
1717 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1718 $sth->execute($itemnum);
1719 my $data = $sth->fetchrow_hashref;
1721 my $query = "Insert into deleteditems set ";
1723 foreach my $temp ( keys %$data ) {
1724 $query .= "$temp = ?,";
1725 push ( @bind, $data->{$temp} );
1730 $sth = $dbh->prepare($query);
1731 $sth->execute(@bind);
1733 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1734 $sth->execute($itemnum);
1740 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1744 deletes a biblioitem
1745 NOTE : not standard sub name. Should be REALdelbiblioitem()
1751 sub REALdelbiblioitem {
1752 my ( $dbh, $biblioitemnumber ) = @_;
1754 # my $dbh = C4Connect;
1755 my $sth = $dbh->prepare( "Select * from biblioitems
1756 where biblioitemnumber = ?"
1760 $sth->execute($biblioitemnumber);
1762 if ( $results = $sth->fetchrow_hashref ) {
1766 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1767 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1768 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1772 $results->{biblioitemnumber}, $results->{biblionumber},
1773 $results->{volume}, $results->{number},
1774 $results->{classification}, $results->{itemtype},
1775 $results->{isbn}, $results->{issn},
1776 $results->{dewey}, $results->{subclass},
1777 $results->{publicationyear}, $results->{publishercode},
1778 $results->{volumedate}, $results->{volumeddesc},
1779 $results->{timestamp}, $results->{illus},
1780 $results->{pages}, $results->{notes},
1781 $results->{size}, $results->{url},
1785 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1786 $sth2->execute($biblioitemnumber);
1791 # Now delete all the items attached to the biblioitem
1792 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1793 $sth->execute($biblioitemnumber);
1795 while ( my $data = $sth->fetchrow_hashref ) {
1796 my $query = "Insert into deleteditems set ";
1798 foreach my $temp ( keys %$data ) {
1799 $query .= "$temp = ?,";
1800 push ( @bind, $data->{$temp} );
1803 my $sth2 = $dbh->prepare($query);
1804 $sth2->execute(@bind);
1807 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1808 $sth->execute($biblioitemnumber);
1812 } # sub deletebiblioitem
1814 =head2 REALdelbiblio($dbh,$biblio);
1825 my ( $dbh, $biblio ) = @_;
1826 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1827 $sth->execute($biblio);
1828 if ( my $data = $sth->fetchrow_hashref ) {
1830 my $query = "Insert into deletedbiblio set ";
1832 foreach my $temp ( keys %$data ) {
1833 $query .= "$temp = ?,";
1834 push ( @bind, $data->{$temp} );
1837 #replacing the last , by ",?)"
1839 $sth = $dbh->prepare($query);
1840 $sth->execute(@bind);
1842 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1843 $sth->execute($biblio);
1851 $number = itemcount($biblio);
1855 returns the number of items attached to a biblio
1863 my $dbh = C4::Context->dbh;
1866 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1867 $sth->execute($biblio);
1868 my $data = $sth->fetchrow_hashref;
1870 return ( $data->{'count(*)'} );
1875 $biblionumber = newbiblio($biblio);
1879 create a biblio. The parameter is a hash
1887 my $dbh = C4::Context->dbh;
1888 my $bibnum = REALnewbiblio( $dbh, $biblio );
1889 # finds new (MARC bibid
1890 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1891 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1892 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1898 $biblionumber = &modbiblio($biblio);
1902 Update a biblio record.
1904 C<$biblio> is a reference-to-hash whose keys are the fields in the
1905 biblio table in the Koha database. All fields must be present, not
1906 just the ones you wish to change.
1908 C<&modbiblio> updates the record defined by
1909 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1911 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1920 my $dbh = C4::Context->dbh;
1921 my $biblionumber=REALmodbiblio($dbh,$biblio);
1922 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1923 # finds new (MARC bibid
1924 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1925 MARCmodbiblio($dbh,$bibid,$record,"",0);
1926 return($biblionumber);
1929 =head2 &modsubtitle($biblionumber, $subtitle);
1933 Sets the subtitle of a book.
1935 C<$biblionumber> is the biblionumber of the book to modify.
1937 C<$subtitle> is the new subtitle.
1944 my ( $bibnum, $subtitle ) = @_;
1945 my $dbh = C4::Context->dbh;
1946 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1949 =head2 &modaddauthor($biblionumber, $author);
1953 Replaces all additional authors for the book with biblio number
1954 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1955 C<&modaddauthor> deletes all additional authors.
1962 my ( $bibnum, @authors ) = @_;
1963 my $dbh = C4::Context->dbh;
1964 &REALmodaddauthor( $dbh, $bibnum, @authors );
1965 } # sub modaddauthor
1969 $error = &modsubject($biblionumber, $force, @subjects);
1973 $force - a subject to force
1974 $error - Error message, or undef if successful.
1981 my ( $bibnum, $force, @subject ) = @_;
1982 my $dbh = C4::Context->dbh;
1983 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1985 # When MARC is off, ensures that the MARC biblio table gets updated with new
1986 # subjects, of course, it deletes the biblio in marc, and then recreates.
1987 # This check is to ensure that no MARC data exists to lose.
1988 # if (C4::Context->preference("MARC") eq '0'){
1989 # warn "in modSUBJECT";
1990 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1991 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1992 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1998 =head2 modbibitem($dbh, $biblioitem);
2002 modify a biblioitem. The parameter is a hash
2009 my ($dbh, $biblioitem) = @_;
2010 #my $dbh = C4::Context->dbh;
2011 &REALmodbiblioitem( $dbh, $biblioitem );
2014 =head2 newbiblioitem
2016 $biblioitemnumber = newbiblioitem($biblioitem)
2020 create a biblioitem, the parameter is a hash
2027 my ($biblioitem) = @_;
2028 my $dbh = C4::Context->dbh;
2029 # add biblio information to the hash
2030 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
2031 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
2032 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
2033 return ($bibitemnum);
2036 =head2 newsubtitle($biblionumber,$subtitle);
2040 insert a subtitle for $biblionumber biblio
2048 my ( $bibnum, $subtitle ) = @_;
2049 my $dbh = C4::Context->dbh;
2050 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2055 $errors = newitems($dbh, $item, @barcodes);
2059 insert items ($item is a hash)
2067 my ( $dbh, $item, @barcodes ) = @_;
2068 #my $dbh = C4::Context->dbh;
2072 foreach my $barcode (@barcodes) {
2073 # add items, one by one for each barcode.
2075 $oneitem->{barcode}= $barcode;
2076 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2077 $oneitem->{marc} = $MARCitem->as_usmarc;
2078 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2079 # $errors .= $error;
2080 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2085 =head2 moditem($dbh,$item);
2089 modify an item ($item is a hash with all item informations)
2097 my ($dbh, $item) = @_;
2098 #my $dbh = C4::Context->dbh;
2099 &REALmoditem( $dbh, $item );
2101 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2103 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2104 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2109 $error = checkitems($count,@barcodes);
2113 check for each @barcode entry that the barcode is not a duplicate
2120 my ( $count, @barcodes ) = @_;
2121 my $dbh = C4::Context->dbh;
2123 my $sth = $dbh->prepare("Select * from items where barcode=?");
2124 for ( my $i = 0 ; $i < $count ; $i++ ) {
2125 $barcodes[$i] = uc $barcodes[$i];
2126 $sth->execute( $barcodes[$i] );
2127 if ( my $data = $sth->fetchrow_hashref ) {
2128 $error .= " Duplicate Barcode: $barcodes[$i]";
2135 =head2 delitem($itemnum);
2139 delete item $itemnum being the item number to delete
2147 my $dbh = C4::Context->dbh;
2148 &REALdelitem( $dbh, $itemnum );
2151 =head2 deletebiblioitem($biblioitemnumber);
2155 delete the biblioitem $biblioitemnumber
2161 sub deletebiblioitem {
2162 my ($biblioitemnumber) = @_;
2163 my $dbh = C4::Context->dbh;
2164 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2165 } # sub deletebiblioitem
2167 =head2 delbiblio($biblionumber)
2171 delete biblio $biblionumber
2179 my $dbh = C4::Context->dbh;
2180 &REALdelbiblio( $dbh, $biblio );
2181 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2182 &MARCdelbiblio( $dbh, $bibid, 0 );
2187 ($count,@results) = getbiblio($biblionumber);
2191 return an array with hash of biblios.
2193 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2200 my ($biblionumber) = @_;
2201 my $dbh = C4::Context->dbh;
2202 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2204 # || die "Cannot prepare $query\n" . $dbh->errstr;
2208 $sth->execute($biblionumber);
2210 # || die "Cannot execute $query\n" . $sth->errstr;
2211 while ( my $data = $sth->fetchrow_hashref ) {
2212 $results[$count] = $data;
2217 return ( $count, @results );
2222 $data = &bibdata($biblionumber, $type);
2224 Returns information about the book with the given biblionumber.
2226 C<$type> is ignored.
2228 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2229 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2232 In addition, C<$data-E<gt>{subject}> is the list of the book's
2233 subjects, separated by C<" , "> (space, comma, space).
2235 If there are multiple biblioitems with the given biblionumber, only
2236 the first one is considered.
2241 my ($bibnum, $type) = @_;
2242 my $dbh = C4::Context->dbh;
2243 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2245 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2246 left join bibliosubtitle on
2247 biblio.biblionumber = bibliosubtitle.biblionumber
2248 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2249 where biblio.biblionumber = ?
2251 $sth->execute($bibnum);
2253 $data = $sth->fetchrow_hashref;
2255 # handle management of repeated subtitle
2256 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2257 $sth->execute($bibnum);
2259 while (my $dat = $sth->fetchrow_hashref){
2261 $line{subtitle} = $dat->{subtitle};
2262 push @subtitles, \%line;
2264 $data->{subtitles} = \@subtitles;
2266 $sth = $dbh->prepare("SELECT * FROM bibliosubject
2268 AND biblionumber = ?");
2269 $sth->execute($bibnum);
2271 while (my $dat = $sth->fetchrow_hashref){
2273 $line{subject} = $dat->{'subject'};
2274 push @subjects, \%line;
2276 $data->{subjects} = \@subjects;
2278 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2279 $sth->execute($bibnum);
2280 while (my $dat = $sth->fetchrow_hashref){
2281 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2283 chop $data->{'additionalauthors'};
2284 chop $data->{'additionalauthors'};
2285 chop $data->{'additionalauthors'};
2290 =head2 getbiblioitem
2292 ($count,@results) = getbiblioitem($biblioitemnumber);
2296 return an array with hash of biblioitemss.
2298 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2305 my ($biblioitemnum) = @_;
2306 my $dbh = C4::Context->dbh;
2307 my $sth = $dbh->prepare( "Select * from biblioitems where
2308 biblioitemnumber = ?"
2313 $sth->execute($biblioitemnum);
2315 while ( my $data = $sth->fetchrow_hashref ) {
2316 $results[$count] = $data;
2321 return ( $count, @results );
2322 } # sub getbiblioitem
2324 =head2 getbiblioitembybiblionumber
2326 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2330 return an array with hash of biblioitems for the given biblionumber.
2336 sub getbiblioitembybiblionumber {
2337 my ($biblionumber) = @_;
2338 my $dbh = C4::Context->dbh;
2339 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2343 $sth->execute($biblionumber);
2345 while ( my $data = $sth->fetchrow_hashref ) {
2346 $results[$count] = $data;
2351 return ( $count, @results );
2354 =head2 getitemsbybiblioitem
2356 ($count,@results) = getitemsbybiblioitem($biblionumber);
2360 returns an array with hash of items
2366 sub getitemsbybiblioitem {
2367 my ($biblioitemnum) = @_;
2368 my $dbh = C4::Context->dbh;
2369 my $sth = $dbh->prepare( "Select * from items, biblio where
2370 biblio.biblionumber = items.biblionumber and biblioitemnumber
2374 # || die "Cannot prepare $query\n" . $dbh->errstr;
2378 $sth->execute($biblioitemnum);
2380 # || die "Cannot execute $query\n" . $sth->errstr;
2381 while ( my $data = $sth->fetchrow_hashref ) {
2382 $results[$count] = $data;
2387 return ( $count, @results );
2388 } # sub getitemsbybiblioitem
2392 @results = &ItemInfo($env, $biblionumber, $type);
2394 Returns information about books with the given biblionumber.
2396 C<$type> may be either C<intra> or anything else. If it is not set to
2397 C<intra>, then the search will exclude lost, very overdue, and
2402 C<&ItemInfo> returns a list of references-to-hash. Each element
2403 contains a number of keys. Most of them are table items from the
2404 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2405 Koha database. Other keys include:
2409 =item C<$data-E<gt>{branchname}>
2411 The name (not the code) of the branch to which the book belongs.
2413 =item C<$data-E<gt>{datelastseen}>
2415 This is simply C<items.datelastseen>, except that while the date is
2416 stored in YYYY-MM-DD format in the database, here it is converted to
2417 DD/MM/YYYY format. A NULL date is returned as C<//>.
2419 =item C<$data-E<gt>{datedue}>
2421 =item C<$data-E<gt>{class}>
2423 This is the concatenation of C<biblioitems.classification>, the book's
2424 Dewey code, and C<biblioitems.subclass>.
2426 =item C<$data-E<gt>{ocount}>
2428 I think this is the number of copies of the book available.
2430 =item C<$data-E<gt>{order}>
2432 If this is set, it is set to C<One Order>.
2439 my ($env,$biblionumber,$type) = @_;
2440 my $dbh = C4::Context->dbh;
2441 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2442 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2443 WHERE items.biblionumber = ?
2444 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2445 AND biblio.biblionumber = items.biblionumber";
2446 $query .= " order by items.dateaccessioned desc";
2447 my $sth=$dbh->prepare($query);
2448 $sth->execute($biblionumber);
2451 while (my $data=$sth->fetchrow_hashref){
2453 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2454 $isth->execute($data->{'itemnumber'});
2455 if (my $idata=$isth->fetchrow_hashref){
2456 $data->{borrowernumber} = $idata->{borrowernumber};
2457 $data->{cardnumber} = $idata->{cardnumber};
2458 $datedue = format_date($idata->{'date_due'});
2460 if ($datedue eq ''){
2461 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2467 #get branch information.....
2468 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2469 $bsth->execute($data->{'holdingbranch'});
2470 if (my $bdata=$bsth->fetchrow_hashref){
2471 $data->{'branchname'} = $bdata->{'branchname'};
2473 my $date=format_date($data->{'datelastseen'});
2474 $data->{'datelastseen'}=$date;
2475 $data->{'datedue'}=$datedue;
2476 # get notforloan complete status if applicable
2477 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2478 $sthnflstatus->execute;
2479 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2480 if ($authorised_valuecode) {
2481 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2482 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2483 my ($lib) = $sthnflstatus->fetchrow;
2484 $data->{notforloan} = $lib;
2495 ($count, @results) = &bibitems($biblionumber);
2497 Given the biblionumber for a book, C<&bibitems> looks up that book's
2498 biblioitems (different publications of the same book, the audio book
2499 and film versions, etc.).
2501 C<$count> is the number of elements in C<@results>.
2503 C<@results> is an array of references-to-hash; the keys are the fields
2504 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2505 addition, C<itemlost> indicates the availability of the item: if it is
2506 "2", then all copies of the item are long overdue; if it is "1", then
2507 all copies are lost; otherwise, there is at least one copy available.
2514 my $dbh = C4::Context->dbh;
2515 my $sth = $dbh->prepare("SELECT biblioitems.*,
2517 MIN(items.itemlost) as itemlost,
2518 MIN(items.dateaccessioned) as dateaccessioned
2519 FROM biblioitems, itemtypes, items
2520 WHERE biblioitems.biblionumber = ?
2521 AND biblioitems.itemtype = itemtypes.itemtype
2522 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2523 GROUP BY items.biblioitemnumber");
2526 $sth->execute($bibnum);
2527 while (my $data = $sth->fetchrow_hashref) {
2528 $results[$count] = $data;
2532 return($count, @results);
2538 $itemdata = &bibitemdata($biblioitemnumber);
2540 Looks up the biblioitem with the given biblioitemnumber. Returns a
2541 reference-to-hash. The keys are the fields from the C<biblio>,
2542 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2543 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2549 my $dbh = C4::Context->dbh;
2550 my $sth = $dbh->prepare("Select *,biblioitems.notes as bnotes from biblio, biblioitems,itemtypes where biblio.biblionumber = biblioitems.biblionumber and biblioitemnumber = ? and biblioitems.itemtype = itemtypes.itemtype");
2553 $sth->execute($bibitem);
2555 $data = $sth->fetchrow_hashref;
2562 =head2 getbibliofromitemnumber
2564 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2566 Looks up the item with the given itemnumber.
2568 C<$env> and C<$dbh> are ignored.
2570 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2571 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2576 sub getbibliofromitemnumber {
2577 my ($env,$dbh,$itemnumber) = @_;
2578 $dbh = C4::Context->dbh;
2579 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2580 where items.itemnumber = ?
2581 and biblio.biblionumber = items.biblionumber
2582 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2584 $sth->execute($itemnumber);
2585 my $data=$sth->fetchrow_hashref;
2592 @barcodes = &barcodes($biblioitemnumber);
2594 Given a biblioitemnumber, looks up the corresponding items.
2596 Returns an array of references-to-hash; the keys are C<barcode> and
2599 The returned items include very overdue items, but not lost ones.
2604 #called from request.pl
2605 my ($biblioitemnumber)=@_;
2606 my $dbh = C4::Context->dbh;
2607 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2608 WHERE biblioitemnumber = ?
2609 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2610 $sth->execute($biblioitemnumber);
2613 while (my $data=$sth->fetchrow_hashref){
2614 $barcodes[$i]=$data;
2624 $item = &itemdata($barcode);
2626 Looks up the item with the given barcode, and returns a
2627 reference-to-hash containing information about that item. The keys of
2628 the hash are the fields from the C<items> and C<biblioitems> tables in
2633 sub get_item_from_barcode {
2635 my $dbh = C4::Context->dbh;
2636 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2637 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2638 $sth->execute($barcode);
2639 my $data=$sth->fetchrow_hashref;
2647 @issues = &itemissues($biblioitemnumber, $biblio);
2649 Looks up information about who has borrowed the bookZ<>(s) with the
2650 given biblioitemnumber.
2652 C<$biblio> is ignored.
2654 C<&itemissues> returns an array of references-to-hash. The keys
2655 include the fields from the C<items> table in the Koha database.
2656 Additional keys include:
2662 If the item is currently on loan, this gives the due date.
2664 If the item is not on loan, then this is either "Available" or
2665 "Cancelled", if the item has been withdrawn.
2669 If the item is currently on loan, this gives the card number of the
2670 patron who currently has the item.
2672 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2674 These give the timestamp for the last three times the item was
2677 =item C<card0>, C<card1>, C<card2>
2679 The card number of the last three patrons who borrowed this item.
2681 =item C<borrower0>, C<borrower1>, C<borrower2>
2683 The borrower number of the last three patrons who borrowed this item.
2690 my ($bibitem, $biblio)=@_;
2691 my $dbh = C4::Context->dbh;
2692 # FIXME - If this function die()s, the script will abort, and the
2693 # user won't get anything; depending on how far the script has
2694 # gotten, the user might get a blank page. It would be much better
2695 # to at least print an error message. The easiest way to do this
2696 # is to set $SIG{__DIE__}.
2697 my $sth = $dbh->prepare("Select * from items where
2698 items.biblioitemnumber = ?")
2699 || die $dbh->errstr;
2703 $sth->execute($bibitem)
2704 || die $sth->errstr;
2706 while (my $data = $sth->fetchrow_hashref) {
2707 # Find out who currently has this item.
2708 # FIXME - Wouldn't it be better to do this as a left join of
2709 # some sort? Currently, this code assumes that if
2710 # fetchrow_hashref() fails, then the book is on the shelf.
2711 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2712 # database server crash), not just because no items match the
2714 my $sth2 = $dbh->prepare("select * from issues,borrowers
2715 where itemnumber = ?
2716 and returndate is NULL
2717 and issues.borrowernumber = borrowers.borrowernumber");
2719 $sth2->execute($data->{'itemnumber'});
2720 if (my $data2 = $sth2->fetchrow_hashref) {
2721 $data->{'date_due'} = $data2->{'date_due'};
2722 $data->{'card'} = $data2->{'cardnumber'};
2723 $data->{'borrower'} = $data2->{'borrowernumber'};
2725 if ($data->{'wthdrawn'} eq '1') {
2726 $data->{'date_due'} = 'Cancelled';
2728 $data->{'date_due'} = 'Available';
2734 # Find the last 3 people who borrowed this item.
2735 $sth2 = $dbh->prepare("select * from issues, borrowers
2736 where itemnumber = ?
2737 and issues.borrowernumber = borrowers.borrowernumber
2738 and returndate is not NULL
2739 order by returndate desc,timestamp desc") || die $dbh->errstr;
2740 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2741 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2742 if (my $data2 = $sth2->fetchrow_hashref) {
2743 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2744 $data->{"card$i2"} = $data2->{'cardnumber'};
2745 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2750 $results[$i] = $data;
2760 ($count, $subjects) = &getsubject($biblionumber);
2762 Looks up the subjects of the book with the given biblionumber. Returns
2763 a two-element list. C<$subjects> is a reference-to-array, where each
2764 element is a subject of the book, and C<$count> is the number of
2765 elements in C<$subjects>.
2771 my $dbh = C4::Context->dbh;
2772 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2773 $sth->execute($bibnum);
2776 while (my $data=$sth->fetchrow_hashref){
2781 return($i,\@results);
2786 ($count, $authors) = &getaddauthor($biblionumber);
2788 Looks up the additional authors for the book with the given
2791 Returns a two-element list. C<$authors> is a reference-to-array, where
2792 each element is an additional author, and C<$count> is the number of
2793 elements in C<$authors>.
2799 my $dbh = C4::Context->dbh;
2800 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2801 $sth->execute($bibnum);
2804 while (my $data=$sth->fetchrow_hashref){
2809 return($i,\@results);
2815 ($count, $subtitles) = &getsubtitle($biblionumber);
2817 Looks up the subtitles for the book with the given biblionumber.
2819 Returns a two-element list. C<$subtitles> is a reference-to-array,
2820 where each element is a subtitle, and C<$count> is the number of
2821 elements in C<$subtitles>.
2827 my $dbh = C4::Context->dbh;
2828 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2829 $sth->execute($bibnum);
2832 while (my $data=$sth->fetchrow_hashref){
2837 return($i,\@results);
2843 ($count, @websites) = &getwebsites($biblionumber);
2845 Looks up the web sites pertaining to the book with the given
2848 C<$count> is the number of elements in C<@websites>.
2850 C<@websites> is an array of references-to-hash; the keys are the
2851 fields from the C<websites> table in the Koha database.
2854 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2855 #(with add / modify / delete subs)
2858 my ($biblionumber) = @_;
2859 my $dbh = C4::Context->dbh;
2860 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2864 $sth->execute($biblionumber);
2865 while (my $data = $sth->fetchrow_hashref) {
2866 # FIXME - The URL scheme shouldn't be stripped off, at least
2867 # not here, since it's part of the URL, and will be useful in
2868 # constructing a link to the site. If you don't want the user
2869 # to see the "http://" part, strip that off when building the
2871 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2873 $results[$count] = $data;
2878 return($count, @results);
2881 =head2 getwebbiblioitems
2883 ($count, @results) = &getwebbiblioitems($biblionumber);
2885 Given a book's biblionumber, looks up the web versions of the book
2886 (biblioitems with itemtype C<WEB>).
2888 C<$count> is the number of items in C<@results>. C<@results> is an
2889 array of references-to-hash; the keys are the items from the
2890 C<biblioitems> table of the Koha database.
2894 sub getwebbiblioitems {
2895 my ($biblionumber) = @_;
2896 my $dbh = C4::Context->dbh;
2897 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2898 and itemtype = 'WEB'");
2902 $sth->execute($biblionumber);
2903 while (my $data = $sth->fetchrow_hashref) {
2904 $data->{'url'} =~ s/^http:\/\///;
2905 $results[$count] = $data;
2910 return($count, @results);
2911 } # sub getwebbiblioitems
2914 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2915 my $NSE = '\x89'; # NSE : Non Sorting Block end
2916 # handles non sorting blocks
2920 s/[ ]{0,1}$NSE/) /gm;
2927 my $dbh = C4::Context->dbh;
2928 my $result = MARCmarc2koha($dbh,$record,'');
2930 my ($biblionumber,$bibid,$title);
2931 # search duplicate on ISBN, easy and fast...
2932 if ($result->{isbn}) {
2933 $sth = $dbh->prepare("select biblio.biblionumber,bibid,title from biblio,biblioitems,marc_biblio where biblio.biblionumber=biblioitems.biblionumber and marc_biblio.biblionumber=biblioitems.biblionumber and isbn=?");
2934 $sth->execute($result->{'isbn'});
2935 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2936 return $biblionumber,$bibid,$title if ($biblionumber);
2938 # a more complex search : build a request for SearchMarc::catalogsearch()
2939 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2940 # search on biblio.title
2941 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2942 if ($record->field($tag)) {
2943 if ($record->field($tag)->subfields($subfield)) {
2944 push @tags, "'".$tag.$subfield."'";
2945 push @and_or, "and";
2946 push @excluding, "";
2947 push @operator, "contains";
2948 push @value, $record->field($tag)->subfield($subfield);
2949 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2952 # ... and on biblio.author
2953 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2954 if ($record->field($tag)) {
2955 if ($record->field($tag)->subfields($subfield)) {
2956 push @tags, "'".$tag.$subfield."'";
2957 push @and_or, "and";
2958 push @excluding, "";
2959 push @operator, "contains";
2960 push @value, $record->field($tag)->subfield($subfield);
2961 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2964 # ... and on publicationyear.
2965 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2966 if ($record->field($tag)) {
2967 if ($record->field($tag)->subfields($subfield)) {
2968 push @tags, "'".$tag.$subfield."'";
2969 push @and_or, "and";
2970 push @excluding, "";
2971 push @operator, "=";
2972 push @value, $record->field($tag)->subfield($subfield);
2973 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2977 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2978 if ($record->field($tag)) {
2979 if ($record->field($tag)->subfields($subfield)) {
2980 push @tags, "'".$tag.$subfield."'";
2981 push @and_or, "and";
2982 push @excluding, "";
2983 push @operator, "=";
2984 push @value, $record->field($tag)->subfield($subfield);
2985 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2988 # ... and on publisher.
2989 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2990 if ($record->field($tag)) {
2991 if ($record->field($tag)->subfields($subfield)) {
2992 push @tags, "'".$tag.$subfield."'";
2993 push @and_or, "and";
2994 push @excluding, "";
2995 push @operator, "=";
2996 push @value, $record->field($tag)->subfield($subfield);
2997 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
3000 # ... and on volume.
3001 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
3002 if ($record->field($tag)) {
3003 if ($record->field($tag)->subfields($subfield)) {
3004 push @tags, "'".$tag.$subfield."'";
3005 push @and_or, "and";
3006 push @excluding, "";
3007 push @operator, "=";
3008 push @value, $record->field($tag)->subfield($subfield);
3009 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
3013 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
3014 # there is at least 1 result => return the 1st one
3016 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
3017 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
3019 # no result, returns nothing
3026 if(substr($isbn, 0, 1) <=7) {
3027 $seg1 = substr($isbn, 0, 1);
3028 } elsif(substr($isbn, 0, 2) <= 94) {
3029 $seg1 = substr($isbn, 0, 2);
3030 } elsif(substr($isbn, 0, 3) <= 995) {
3031 $seg1 = substr($isbn, 0, 3);
3032 } elsif(substr($isbn, 0, 4) <= 9989) {
3033 $seg1 = substr($isbn, 0, 4);
3035 $seg1 = substr($isbn, 0, 5);
3037 my $x = substr($isbn, length($seg1));
3039 if(substr($x, 0, 2) <= 19) {
3040 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
3041 $seg2 = substr($x, 0, 2);
3042 } elsif(substr($x, 0, 3) <= 699) {
3043 $seg2 = substr($x, 0, 3);
3044 } elsif(substr($x, 0, 4) <= 8399) {
3045 $seg2 = substr($x, 0, 4);
3046 } elsif(substr($x, 0, 5) <= 89999) {
3047 $seg2 = substr($x, 0, 5);
3048 } elsif(substr($x, 0, 6) <= 9499999) {
3049 $seg2 = substr($x, 0, 6);
3051 $seg2 = substr($x, 0, 7);
3053 my $seg3=substr($x,length($seg2));
3054 $seg3=substr($seg3,0,length($seg3)-1) ;
3055 my $seg4 = substr($x, -1, 1);
3056 return "$seg1-$seg2-$seg3-$seg4";
3059 =head2 get_itemnumbers_of
3061 my @itemnumbers_of = get_itemnumbers_of(@biblionumbers);
3063 Given a list of biblionumbers, return the list of corresponding itemnumbers
3064 for each biblionumber.
3066 Return a reference on a hash where keys are biblionumbers and values are
3067 references on array of itemnumbers.
3070 sub get_itemnumbers_of {
3071 my @biblionumbers = @_;
3073 my $dbh = C4::Context->dbh;
3079 WHERE biblionumber IN (?'.(',?' x scalar @biblionumbers - 1).')
3081 my $sth = $dbh->prepare($query);
3082 $sth->execute(@biblionumbers);
3086 while (my ($itemnumber, $biblionumber) = $sth->fetchrow_array) {
3087 push @{$itemnumbers_of{$biblionumber}}, $itemnumber;
3090 return \%itemnumbers_of;
3093 sub get_iteminfos_of {
3094 my @itemnumbers = @_;
3099 WHERE itemnumber IN ('.join(',', @itemnumbers).')
3101 return get_infos_of($query, 'itemnumber');
3104 sub get_biblioiteminfos_of {
3105 my @biblioitemnumbers = @_;
3108 SELECT biblioitemnumber,
3112 WHERE biblioitemnumber IN ('.join(',', @biblioitemnumbers).')
3115 return get_infos_of($query, 'biblioitemnumber');
3118 END { } # module clean-up code here (global destructor)
3124 Koha Developement team <info@koha.org>
3126 Paul POULAIN paul.poulain@free.fr
3132 # Revision 1.172 2006/06/06 23:13:14 bob_lyon
3133 # Merging katipo changes...
3135 # altering subject search to stop returning blank rows
3137 # Revision 1.171 2006/05/17 16:06:24 plg
3138 # New feature from SAN Ouest Provence: ability to reserve a specific item in
3139 # the intranet. The development was made on branch 2.2 by Arnaud Laurin from
3140 # Ouest Provence and integrated on HEAD by Pierrick Le Gall from INEO media
3143 # New page reserve/request.pl taking a biblionumber as entry point.
3147 # - C4::Biblio::get_iteminfos_of retrieves item informations for a list of
3150 # - C4::Biblio::get_biblioiteminfos_of retrieves biblioitem informations for a
3151 # list of biblioitemnumbers
3153 # - C4::Biblio::get_itemnumbers_of retrieve the list of itemnumbers related to
3154 # each biblionumber given in argument.
3156 # - C4::Circulation::Circ2::get_return_date_of retrieves return date for a
3157 # list of itemnumbers.
3159 # - C4::Koha::get_itemtypeinfos_of retrieves the informations related to a
3160 # list of itemtypes.
3162 # - C4::Koha::get_branchinfos_of retrieves the informations related to a list
3165 # - C4::Koha::get_notforloan_label_of retrives the list of status/label for
3166 # the authorised_values related to notforloan.
3168 # - C4::Koha::get_infos_of is the generic function used by all get_*infos_of.
3170 # - C4::Reserves2::GetNumberReservesFromBorrower
3172 # - C4::Reserves2::GetFirstReserveDateFromItem
3174 # Modified functions:
3176 # - C4::Reserves2::FindReserves was simplified to be more readable.
3178 # The reservation page is reserve/request.pl and is linked from nowhere as
3179 # long as zebra is not stable yet on HEAD.
3181 # Revision 1.170 2006/04/15 02:47:47 tgarip1957
3182 # Change the MARC Leader to UTF-8 incase user did not set it. Important for Zebra.
3183 # The new M::F::XML is sensitive to leader settings
3185 # Revision 1.169 2006/04/10 20:39:49 tgarip1957
3186 # New sub to use by Circ2.pm . Allows one subfield of MARC holdings fields to be updated to use with branch transfer(holdingbranch) and onloan flag when set
3188 # Revision 1.168 2006/04/03 04:00:02 rangi
3189 # Modify item now works
3191 # BUT only if there is only one item, if there is more than one item, it gets messed up.
3192 # They get combined into the form, ill work on this next
3194 # Revision 1.167 2006/04/03 02:12:49 kados
3195 # some modifs to improve plugin support
3197 # Revision 1.166 2006/04/01 22:10:50 rangi
3198 # Fixing the problem that all items were getting biblioitem=1 set
3200 # Revision 1.165 2006/04/01 21:22:05 rangi
3201 # Adding a little fake subroutine that a few scripts in the opac depend on, can be removed once the opac scripts are rewritten
3203 # Revision 1.164 2006/03/29 01:56:25 rangi
3204 # Delete isnt working using the extended services method
3206 # Revision 1.163 2006/03/28 23:05:08 rangi
3207 # Delete working now
3209 # Revision 1.162 2006/03/13 23:12:44 rangi
3210 # Adding commits, so that changes stick
3212 # Revision 1.161 2006/03/10 02:40:38 kados
3213 # syncing MARChtml2xml wtih rel_2_2, removing unused MARChtml2marc
3215 # Revision 1.160 2006/03/07 22:00:18 kados
3216 # adding support for 'delete' function
3218 # Revision 1.159 2006/03/07 21:54:47 rangi
3219 # Starting work on deletes
3221 # Revision 1.158 2006/03/06 02:45:41 kados
3222 # Adding fixes to MARC editor to HEAD
3224 # Revision 1.157 2006/03/01 03:07:54 kados
3225 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3227 # Revision 1.155 2006/02/27 01:08:31 kados
3228 # Removing 'our Zconn' from top...
3230 # Revision 1.154 2006/02/26 00:08:20 kados
3231 # moving all $Zconn s to z3950_extended_services (currently, nothing
3234 # Revision 1.153 2006/02/25 22:39:10 kados
3235 # Another purely documentation commit. Just changing formatting to ease
3238 # Revision 1.152 2006/02/25 21:17:20 kados
3239 # Purely documentation change: converted all =head2 entries to use function
3240 # name as title rather than usage as title
3242 # Revision 1.151 2006/02/25 21:02:20 kados
3244 # Further cleanup, convering new routines to 4-chars
3246 # Revision 1.150 2006/02/25 20:49:15 kados
3247 # Better documentation, added warning if serviceType is 'drop' since it's
3248 # not supported in Zebra.
3250 # Revision 1.149 2006/02/25 20:30:32 kados
3251 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3252 # longer necessary. If we need to convert from MARC-8 for display, we should:
3255 # 2. do it with MARC::Charset
3257 # If you still need it, let me know and I'll put it back in.
3259 # Revision 1.148 2006/02/25 19:23:01 kados
3260 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3261 # replaced by z3950_extended_services).
3263 # Revision 1.147 2006/02/25 19:09:59 kados
3264 # readding some lost subs
3266 # Revision 1.145 2006/02/22 01:02:39 kados
3267 # Replacing all calls to zebra_update with calls to
3268 # z3950_extended_services. More work coming, but it's
3271 # Revision 1.144 2006/02/20 14:22:38 kados
3274 # Revision 1.143 2006/02/20 13:26:11 kados
3275 # A new subroutine to handle Z39.50 extended services. You pass it a
3276 # connection object, service type, service options, and a record, and
3277 # it performs the service and handles any exception found.
3279 # Revision 1.142 2006/02/16 20:49:56 kados
3280 # destroy a connection after we're done -- we really should just have one
3281 # connection object and not destroy it until the whole transaction is
3282 # finished -- but this will do for now
3284 # Revision 1.141 2006/02/16 19:47:22 rangi
3285 # Trying to error trap a little more.
3287 # Revision 1.140 2006/02/14 21:36:03 kados
3288 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3289 # also adding diagnostic error if not able to connect to Zebra
3291 # Revision 1.139 2006/02/14 19:53:25 rangi
3292 # Just a little missing my
3294 # Seems to be working great Paul, and I like what you did with zebradb
3296 # Revision 1.138 2006/02/14 11:25:22 tipaul
3297 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3299 # Revision 1.137 2006/02/13 16:34:26 tipaul
3300 # fixing some warnings (perl -w should be quiet)
3302 # Revision 1.136 2006/01/10 17:01:29 tipaul
3303 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3305 # Revision 1.135 2006/01/06 16:39:37 tipaul
3306 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3307 # Seems not to break too many things, but i'm probably wrong here.
3308 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3310 # - removing useless directories (koha-html and koha-plucene)
3312 # Revision 1.134 2006/01/04 15:54:55 tipaul
3313 # utf8 is a : go for beta test in HEAD.
3314 # some explanations :
3315 # - updater/updatedatabase => will transform all tables in innoDB (not related to utf8, just to warn you) AND collate them in utf8 / utf8_general_ci. The SQL command is : ALTER TABLE tablename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci.
3316 # - *-top.inc will show the pages in utf8
3317 # - THE HARD THING : for me, mysql-client and mysql-server were set up to communicate in iso8859-1, whatever the mysql collation ! Thus, pages were improperly shown, as datas were transmitted in iso8859-1 format ! After a full day of investigation, someone on usenet pointed "set NAMES 'utf8'" to explain that I wanted utf8. I could put this in my.cnf, but if I do that, ALL databases will "speak" in utf8, that's not what we want. Thus, I added a line in Context.pm : everytime a DB handle is opened, the communication is set to utf8.
3318 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3320 # Revision 1.133 2005/12/12 14:25:51 thd
3323 # Reverse array filled with elements from repeated subfields
3324 # to avoid last to first concatenation of elements in Koha DB.-
3326 # Revision 1.132 2005-10-26 09:12:33 tipaul
3327 # big commit, still breaking things...
3329 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3330 # * code cleaning (cleaning warnings from perl -w) continued
3332 # Revision 1.131 2005/09/22 10:01:45 tipaul
3333 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3335 # Revision 1.130 2005/09/02 14:34:14 tipaul
3336 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3337 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3338 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3340 # Revision 1.129 2005/08/12 13:50:31 tipaul
3341 # removing useless sub declarations
3343 # Revision 1.128 2005/08/11 16:12:47 tipaul
3344 # Playing with the zebra...
3346 # * go to koha cvs home directory
3347 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3348 # * put your zebra.cfg files here & create your database.
3349 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3350 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3353 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3354 # * deletion still not work
3355 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3357 # recordId: (bib1,Local-number)
3361 # elm 090 Local-number -
3362 # elm 090/? Local-number -
3363 # elm 090/?/9 Local-number !:w
3365 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3367 # Revision 1.127 2005/08/11 14:37:32 tipaul
3369 # * removing useless subs
3370 # * removing some subs that are also elsewhere
3371 # * renaming all OLDxxx subs to REALxxx subs (should not change anything, as OLDxxx, as well as REAL, are supposed to be for Biblio.pm internal use only)
3373 # Revision 1.126 2005/08/11 09:13:28 tipaul
3374 # just removing useless subs (a lot !!!) for code cleaning
3376 # Revision 1.125 2005/08/11 09:00:07 tipaul
3377 # Ok guys, this time, it seems that item add and modif begin working as expected...
3378 # Still a lot of bugs to fix, of course
3380 # Revision 1.124 2005/08/10 10:21:15 tipaul
3381 # continuing the road to zebra :
3382 # - the biblio add begins to work.
3383 # - the biblio modif begins to work.
3385 # (still without doing anything on zebra)
3386 # (no new change in updatedatabase)
3388 # Revision 1.123 2005/08/09 14:10:28 tipaul
3389 # 1st commit to go to zebra.
3390 # don't update your cvs if you want to have a working head...
3392 # this commit contains :
3393 # * updater/updatedatabase : get rid with marc_* tables, but DON'T remove them. As a lot of things uses them, it would not be a good idea for instance to drop them. If you really want to play, you can rename them to test head without them but being still able to reintroduce them...
3394 # * Biblio.pm : modify MARCgetbiblio to find the raw marc record in biblioitems.marc field, not from marc_subfield_table, modify MARCfindframeworkcode to find frameworkcode in biblio.frameworkcode, modify some other subs to use biblio.biblionumber & get rid of bibid.
3395 # * other files : get rid of bibid and use biblionumber instead.
3398 # * does not do anything on zebra yet.
3399 # * if you rename marc_subfield_table, you can't search anymore.
3400 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3401 # * don't try to add a biblio, it would add data poorly... (don't try to delete either, it may work, but that would be a surprise ;-) )
3403 # IMPORTANT NOTE : you need MARC::XML package (http://search.cpan.org/~esummers/MARC-XML-0.7/lib/MARC/File/XML.pm), that requires a recent version of MARC::Record
3404 # Updatedatabase stores the iso2709 data in biblioitems.marc field & an xml version in biblioitems.marcxml Not sure we will keep it when releasing the stable version, but I think it's a good idea to have something readable in sql, at least for development stage.
3406 # tipaul cutted previous commit notes