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
27 use MARC::File::USMARC;
30 use vars qw($VERSION @ISA @EXPORT);
32 # set the version for version checking
33 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
34 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
39 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
40 # as the old-style API and the NEW one are the only public functions.
43 &newbiblio &newbiblioitem
44 &newsubject &newsubtitle &newitems
46 &modbiblio &checkitems &modbibitem
47 &modsubtitle &modsubject &modaddauthor &moditem
49 &delitem &deletebiblioitem &delbiblio
51 &getbiblio &bibdata &bibitems &bibitemdata
52 &barcodes &ItemInfo &itemdata &itemissues &itemcount
53 &getsubject &getaddauthor &getsubtitle
54 &getwebbiblioitems &getwebsites
55 &getbiblioitembybiblionumber
56 &getbiblioitem &getitemsbybiblioitem
58 &MARCfind_marc_from_kohafield
59 &MARCfind_frameworkcode
60 &find_biblioitemnumber
63 &NEWnewbiblio &NEWnewitem
64 &NEWmodbiblio &NEWmoditem
65 &NEWdelbiblio &NEWdelitem
66 &NEWmodbiblioframework
68 &MARCkoha2marcBiblio &MARCmarc2koha
69 &MARCkoha2marcItem &MARChtml2marc &MARChtml2xml
70 &MARCgetbiblio &MARCgetitem
76 &z3950_extended_services
79 &get_item_from_barcode
80 &MARCfind_MARCbibid_from_oldbiblionumber
86 C4::Biblio - Acquisitions, Catalog Management Functions
90 ( lot of changes for Koha 3.X)
92 Koha 1.2 and previous versions used a specific API to manage biblios. This API uses old-DB style parameters.
93 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors,
94 bibliosubject and bibliosubtitle where applicable).
96 In Koha 2.X, we introduced a MARC-DB.
98 In Koha 3.X, we removed this MARC-DB for search as we wanted to use Zebra as search system.
100 So in Koha 3.X, saving a record means :
102 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items information.
103 - storing the "decoded information" in biblio/biblioitems/items as previously.
104 - using zebra to manage search & indexing on the MARC data.
106 In Koha, there is a systempreference for "MARC=ON" or "MARC=OFF" :
108 * MARC=ON : when MARC=ON, Koha uses a MARC::Record object (in sub parameters). Saving information in the DB means :
110 - transform the MARC record into a hash
111 - add the raw MARC record into the hash
112 - store them & update Zebra
114 * MARC=OFF : when MARC=OFF, Koha uses a hash object (in sub parameters). Saving information in the DB means :
116 - transform the hash into a MARC record
117 - add the raw marc record into the hash
118 - store them & update zebra
120 That's why we need 3 types of subs :
124 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).
126 =head2 NEWxxx related subs
130 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.
132 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. They sometimes require another parameter.
136 =head2 something_elsexxx related subs
140 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.
142 all subs require/use $dbh as 1st parameter and a hash as 2nd parameter.
148 =head2 z3950_extended_services
150 z3950_extended_services($serviceType,$serviceOptions,$record);
152 z3950_extended_services is used to handle all interactions with Zebra's extended serices package.
154 C<$serviceType> one of: itemorder,create,drop,commit,update,xmlupdate
156 C<$serviceOptions> a has of key/value pairs. For instance, if service_type is 'update', $service_options should contain:
158 action => update action, one of specialUpdate, recordInsert, recordReplace, recordDelete, elementUpdate.
162 recordidOpaque => Opaque Record ID (user supplied) or recordidNumber => Record ID number (system number).
163 syntax => the record syntax (transfer syntax)
164 databaseName = Database from connection object
166 To set serviceOptions, call set_service_options($serviceType)
168 C<$record> the record, if one is needed for the service type
170 A record should be in XML. You can convert it to XML from MARC by running it through marc2xml().
173 sub z3950_extended_services {
174 my ($serviceType,$serviceOptions,$record) = @_;
176 my $Zconn = C4::Context->Zconn;
177 # create a new package object
178 my $Zpackage = $Zconn->package();
181 $Zpackage->option(action => $serviceOptions->{'action'});
183 if ($serviceOptions->{'databaseName'}) {
184 $Zpackage->option(databaseName => $serviceOptions->{'databaseName'});
186 if ($serviceOptions->{'recordIdNumber'}) {
187 $Zpackage->option(recordIdNumber => $serviceOptions->{'recordIdNumber'});
189 if ($serviceOptions->{'recordIdOpaque'}) {
190 $Zpackage->option(recordIdOpaque => $serviceOptions->{'recordIdOpaque'});
193 # this is an ILL request (Zebra doesn't support it)
194 #if ($serviceType eq 'itemorder') {
195 # $Zpackage->option('contact-name' => $serviceOptions->{'contact-name'});
196 # $Zpackage->option('contact-phone' => $serviceOptions->{'contact-phone'});
197 # $Zpackage->option('contact-email' => $serviceOptions->{'contact-email'});
198 # $Zpackage->option('itemorder-item' => $serviceOptions->{'itemorder-item'});
202 my $xmlrecord = marc2xml($record);
203 $Zpackage->option(record => $xmlrecord);
204 if ($serviceOptions->{'syntax'}) {
205 $Zpackage->option(syntax => $serviceOptions->{'syntax'});
209 # send the request, handle any exception encountered
210 eval { $Zpackage->send($serviceType) };
211 if ($@ && $@->isa("ZOOM::Exception")) {
212 print "Oops! ", $@->message(), "\n";
215 # free up package resources
216 $Zpackage->destroy();
219 =head2 set_service_options
221 my $serviceOptions = set_service_options($serviceType);
223 C<$serviceType> itemorder,create,drop,commit,update,xmlupdate
225 Currently, we only support 'create', 'commit', and 'update'. 'drop' support will be added as soon as Zebra supports it.
229 sub set_service_options {
230 my ($serviceType) = @_;
233 if ($serviceType eq 'update') {
234 $serviceOptions->{ 'action' } = 'specialUpdate';
236 # FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change
237 # $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml
240 if ($serviceType eq 'commit') {
244 if ($serviceType eq 'create') {
247 if ($serviceType eq 'drop') {
248 die "ERROR: 'drop' not currently supported (by Zebra)";
250 return $serviceOptions;
255 my $xmlrecord = marc2xml($record);
257 Convert from MARC to XML. Note that MARC::File::XML will automatically encode from MARC-8 to UTF-8 as of version .8
259 C<$record> a MARC record
266 eval { $xmlrecord=$record->as_xml() };
267 #TODO: better error handling here
269 warn "ERROR: I suspect a badly formatted MARC record";
274 =head2 MARCgettagslib
276 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
280 2nd param is 1 for liblibrarian and 0 for libopac
281 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
283 returns a hash with all values for all fields and subfields for a given MARC framework :
284 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
286 ->{mandatory} = $mandatory;
287 ->{repeatable} = $repeatable;
288 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
290 ->{mandatory} = $mandatory;
291 ->{repeatable} = $repeatable;
292 ->{authorised_value} = $authorised_value;
293 ->{authtypecode} = $authtypecode;
294 ->{value_builder} = $value_builder;
295 ->{kohafield} = $kohafield;
296 ->{seealso} = $seealso;
297 ->{hidden} = $hidden;
306 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
307 $frameworkcode = "" unless $frameworkcode;
308 $forlibrarian = 1 unless $forlibrarian;
310 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
312 # check that framework exists
315 "select count(*) from marc_tag_structure where frameworkcode=?");
316 $sth->execute($frameworkcode);
317 my ($total) = $sth->fetchrow;
318 $frameworkcode = "" unless ( $total > 0 );
321 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
323 $sth->execute($frameworkcode);
324 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
326 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
327 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
328 $res->{$tag}->{tab} = ""; # XXX
329 $res->{$tag}->{mandatory} = $mandatory;
330 $res->{$tag}->{repeatable} = $repeatable;
335 "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"
337 $sth->execute($frameworkcode);
340 my $authorised_value;
350 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
351 $mandatory, $repeatable, $authorised_value, $authtypecode,
352 $value_builder, $kohafield, $seealso, $hidden,
357 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
358 $res->{$tag}->{$subfield}->{tab} = $tab;
359 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
360 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
361 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
362 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
363 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
364 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
365 $res->{$tag}->{$subfield}->{seealso} = $seealso;
366 $res->{$tag}->{$subfield}->{hidden} = $hidden;
367 $res->{$tag}->{$subfield}->{isurl} = $isurl;
368 $res->{$tag}->{$subfield}->{link} = $link;
373 =head2 MARCfind_marc_from_kohafield
375 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
379 finds MARC tag and subfield for a given kohafield
380 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
386 sub MARCfind_marc_from_kohafield {
387 my ( $dbh, $kohafield,$frameworkcode ) = @_;
388 return 0, 0 unless $kohafield;
389 $frameworkcode='' unless $frameworkcode;
390 my $relations = C4::Context->marcfromkohafield;
391 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
396 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
400 Returns a MARC::Record for the biblio $biblionumber.
406 # Returns MARC::Record of the biblio passed in parameter.
407 my ( $dbh, $biblionumber ) = @_;
408 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
409 $sth->execute($biblionumber);
410 my ($marc) = $sth->fetchrow;
411 my $record = MARC::Record::new_from_usmarc($marc);
417 $XML = &XMLgetbiblio($dbh,$biblionumber);
421 Returns a raw XML for the biblio $biblionumber.
427 # Returns MARC::Record of the biblio passed in parameter.
428 my ( $dbh, $biblionumber ) = @_;
429 my $sth = $dbh->prepare('select marcxml,marc from biblioitems where biblionumber=?');
430 $sth->execute($biblionumber);
431 my ($XML,$marc) = $sth->fetchrow;
432 # my $record =MARC::Record::new_from_usmarc($marc);
433 # warn "MARC : \n*-************************\n".$record->as_xml."\n*-************************\n";
439 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
443 Returns a MARC::Record with all items of biblio # $biblionumber
451 my ( $dbh, $biblionumber, $itemnumber ) = @_;
452 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
453 # get the complete MARC record
454 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
455 $sth->execute($biblionumber);
456 my ($rawmarc) = $sth->fetchrow;
457 my $record = MARC::File::USMARC::decode($rawmarc);
458 # now, find the relevant itemnumber
459 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
460 # prepare the new item record
461 my $itemrecord = MARC::Record->new();
462 # parse all fields fields from the complete record
463 foreach ($record->field($itemnumberfield)) {
464 # when the item field is found, save it
465 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
466 $itemrecord->append_fields($_);
473 =head2 find_biblioitemnumber
475 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
479 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
480 This sub is useless when MARC=OFF
485 sub find_biblioitemnumber {
486 my ( $dbh, $biblionumber ) = @_;
487 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
488 $sth->execute($biblionumber);
489 my ($biblioitemnumber) = $sth->fetchrow;
490 return $biblioitemnumber;
493 =head2 MARCfind_frameworkcode
495 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
499 returns the framework of a given biblio
505 sub MARCfind_frameworkcode {
506 my ( $dbh, $biblionumber ) = @_;
507 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
508 $sth->execute($biblionumber);
509 my ($frameworkcode) = $sth->fetchrow;
510 return $frameworkcode;
513 =head2 MARCkoha2marcBiblio
515 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
519 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
520 all entries of the hash are transformed into their matching MARC field/subfield.
526 sub MARCkoha2marcBiblio {
528 # this function builds partial MARC::Record from the old koha-DB fields
529 my ( $dbh, $bibliohash ) = @_;
530 # we don't have biblio entries in the hash, so we add them first
531 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
532 $sth->execute($bibliohash->{biblionumber});
533 my $biblio = $sth->fetchrow_hashref;
534 foreach (keys %$biblio) {
535 $bibliohash->{$_}=$biblio->{$_};
537 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
538 my $record = MARC::Record->new();
539 foreach ( keys %$bibliohash ) {
540 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
541 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
544 # other fields => additional authors, subjects, subtitles
545 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
546 $sth2->execute($bibliohash->{biblionumber});
547 while ( my $row = $sth2->fetchrow_hashref ) {
548 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
550 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
551 $sth2->execute($bibliohash->{biblionumber});
552 while ( my $row = $sth2->fetchrow_hashref ) {
553 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
555 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
556 $sth2->execute($bibliohash->{biblionumber});
557 while ( my $row = $sth2->fetchrow_hashref ) {
558 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
564 =head2 MARCkoha2marcItem
566 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
568 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
569 all entries of the hash are transformed into their matching MARC field/subfield.
577 sub MARCkoha2marcItem {
579 # this function builds partial MARC::Record from the old koha-DB fields
580 my ( $dbh, $item ) = @_;
582 # my $dbh=&C4Connect;
583 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
584 my $record = MARC::Record->new();
586 foreach( keys %$item ) {
588 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
595 =head2 MARCkoha2marcOnefield
599 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
605 sub MARCkoha2marcOnefield {
606 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
609 $sth->execute($frameworkcode,$kohafieldname);
610 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
611 if ( $record->field($tagfield) ) {
612 my $tag = $record->field($tagfield);
614 $tag->add_subfields( $tagsubfield, $value );
615 $record->delete_field($tag);
616 $record->add_fields($tag);
620 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
627 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
629 transforms the parameters (coming from HTML form) into a MARC::File::XML
630 object. parameters with r are references to arrays
634 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
636 my $xml= MARC::File::XML::header();
641 for (my $i=0;$i<=@$tags;$i++){
643 if ((@$tags[$i] ne $prevtag)){
644 $j++ unless (@$tags[$i] eq "");
645 warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
648 $xml.="</datafield>\n";
652 if (@$values[$i] ne "") {
654 if (@$tags[$i] eq "000") {
655 $xml.="<leader>@$values[$i]</leader>\n";
657 # rest of the fixed fields
658 } elsif (@$tags[$i] < 10) {
659 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
663 my $ind1 = substr(@$indicator[$j],0,1);
664 my $ind2 = substr(@$indicator[$j],1,1);
665 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
666 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
672 if (@$values[$i] eq "") {
676 my $ind1 = substr(@$indicator[$j],0,1);
677 my $ind2 = substr(@$indicator[$j],1,1);
678 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
681 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
685 $prevtag = @$tags[$i];
687 $xml.= MARC::File::XML::footer();
693 $MARCrecord = MARChtml2marc($dbh,$rtags,$rsubfields,$rvalues,%indicators);
697 transforms the parameters (coming from HTML form) into a MARC::Record
698 parameters with r are references to arrays.
700 FIXME : should be improved for 3.0, to avoid having 4 differents arrays
707 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
709 my $record = MARC::Record->new();
710 # my %subfieldlist=();
711 my $prevvalue; # if tag <10
712 my $field; # if tag >=10
713 for (my $i=0; $i< @$rtags; $i++) {
714 next unless @$rvalues[$i];
715 # rebuild MARC::Record
716 # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
717 if (@$rtags[$i] ne $prevtag) {
720 if ($prevtag ne '000') {
721 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
723 $record->leader($prevvalue);
728 $record->add_fields($field);
731 $indicators{@$rtags[$i]}.=' ';
732 if (@$rtags[$i] <10) {
733 $prevvalue= @$rvalues[$i];
737 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
738 # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
740 $prevtag = @$rtags[$i];
742 if (@$rtags[$i] <10) {
743 $prevvalue=@$rvalues[$i];
745 if (length(@$rvalues[$i])>0) {
746 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
747 # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
750 $prevtag= @$rtags[$i];
753 # the last has not been included inside the loop... do it now !
754 $record->add_fields($field) if $field;
755 # warn "HTML2MARC=".$record->as_formatted;
762 $hash = &MARCmarc2koha($dbh,$MARCRecord);
766 builds a hash with old-db datas from a MARC::Record
773 my ($dbh,$record,$frameworkcode) = @_;
774 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
776 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
779 while (($field)=$sth2->fetchrow) {
780 # warn "biblio.".$field;
781 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
783 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
785 while (($field)=$sth2->fetchrow) {
786 if ($field eq 'notes') { $field = 'bnotes'; }
787 # warn "biblioitems".$field;
788 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
790 $sth2=$dbh->prepare("SHOW COLUMNS from items");
792 while (($field)=$sth2->fetchrow) {
793 # warn "items".$field;
794 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
796 # additional authors : specific
797 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
798 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
799 # modify copyrightdate to keep only the 1st year found
800 my $temp = $result->{'copyrightdate'};
802 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
804 $result->{'copyrightdate'} = $1;
805 } else { # if no cYYYY, get the 1st date.
806 $temp =~ m/(\d\d\d\d)/;
807 $result->{'copyrightdate'} = $1;
810 # modify publicationyear to keep only the 1st year found
811 $temp = $result->{'publicationyear'};
812 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
814 $result->{'publicationyear'} = $1;
815 } else { # if no cYYYY, get the 1st date.
816 $temp =~ m/(\d\d\d\d)/;
817 $result->{'publicationyear'} = $1;
822 sub MARCmarc2kohaOneField {
824 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
825 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
826 # warn "kohatable / $kohafield / $result / ";
830 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
831 foreach my $field ( $record->field($tagfield) ) {
832 if ($field->tag()<10) {
833 if ($result->{$kohafield}) {
834 # Reverse array filled with elements from repeated subfields
835 # from first to last to avoid last to first concatenation of
836 # elements in Koha DB. -- thd.
837 $result->{$kohafield} .= " | ".reverse($field->data());
839 $result->{$kohafield} = $field->data();
842 if ( $field->subfields ) {
843 my @subfields = $field->subfields();
844 foreach my $subfieldcount ( 0 .. $#subfields ) {
845 if ($subfields[$subfieldcount][0] eq $subfield) {
846 if ( $result->{$kohafield} ) {
847 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
850 $result->{$kohafield} = $subfields[$subfieldcount][1];
857 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
863 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
867 creates a biblio from a MARC::Record.
874 my ( $dbh,$record,$frameworkcode ) = @_;
876 my $biblioitemnumber;
877 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
878 $olddata->{frameworkcode} = $frameworkcode;
879 $biblionumber = REALnewbiblio( $dbh, $olddata );
880 $olddata->{biblionumber} = $biblionumber;
881 # add biblionumber into the MARC record (it's the ID for zebra)
882 my ( $tagfield, $tagsubfield ) =
883 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
887 $newfield = MARC::Field->new(
888 $tagfield, $biblionumber,
891 $newfield = MARC::Field->new(
892 $tagfield, '', '', "$tagsubfield" => $biblionumber,
895 # drop old field (just in case it already exist and create new one...
896 my $old_field = $record->field($tagfield);
897 $record->delete_field($old_field);
898 $record->add_fields($newfield);
900 #create the marc entry, that stores the rax marc record in Koha 3.0
901 $olddata->{marc} = $record->as_usmarc();
902 $olddata->{marcxml} = $record->as_xml();
903 # and create biblioitem, that's all folks !
904 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
906 # search subtiles, addiauthors and subjects
907 ( $tagfield, $tagsubfield ) =
908 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
909 my @addiauthfields = $record->field($tagfield);
910 foreach my $addiauthfield (@addiauthfields) {
911 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
912 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
913 REALmodaddauthor( $dbh, $biblionumber,
914 $addiauthsubfields[$subfieldcount] );
917 ( $tagfield, $tagsubfield ) =
918 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
919 my @subtitlefields = $record->field($tagfield);
920 foreach my $subtitlefield (@subtitlefields) {
921 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
922 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
923 REALnewsubtitle( $dbh, $biblionumber,
924 $subtitlesubfields[$subfieldcount] );
927 ( $tagfield, $tagsubfield ) =
928 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
929 my @subj = $record->field($tagfield);
931 foreach my $subject (@subj) {
932 my @subjsubfield = $subject->subfield($tagsubfield);
933 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
934 push @subjects, $subjsubfield[$subfieldcount];
937 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
938 return ( $biblionumber, $biblioitemnumber );
941 =head2 NEWmodbilbioframework
943 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
947 modify the framework of a biblio
953 sub NEWmodbiblioframework {
954 my ($dbh,$biblionumber,$frameworkcode) =@_;
955 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
956 $sth->execute($frameworkcode,$biblionumber);
962 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
966 modify a biblio (MARC=ON)
973 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
974 $frameworkcode="" unless $frameworkcode;
975 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
976 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
978 $oldbiblio->{frameworkcode} = $frameworkcode;
979 #create the marc entry, that stores the rax marc record in Koha 3.0
980 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
981 $oldbiblio->{marc} = $record->as_usmarc();
982 $oldbiblio->{marcxml} = $record->as_xml();
983 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
984 REALmodbiblio($dbh,$oldbiblio);
985 REALmodbiblioitem($dbh,$oldbiblio);
986 # now, modify addi authors, subject, addititles.
987 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
988 my @addiauthfields = $record->field($tagfield);
989 foreach my $addiauthfield (@addiauthfields) {
990 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
991 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
992 foreach my $subfieldcount (0..$#addiauthsubfields) {
993 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
996 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
997 my @subtitlefields = $record->field($tagfield);
998 foreach my $subtitlefield (@subtitlefields) {
999 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1000 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
1002 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
1003 foreach my $subfieldcount (0..$#subtitlesubfields) {
1004 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1005 REALnewsubtitle($dbh,$biblionumber,$subtit);
1009 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1010 my @subj = $record->field($tagfield);
1012 foreach my $subject (@subj) {
1013 my @subjsubfield = $subject->subfield($tagsubfield);
1014 foreach my $subfieldcount (0..$#subjsubfield) {
1015 push @subjects,$subjsubfield[$subfieldcount];
1018 REALmodsubject($dbh,$biblionumber,1,@subjects);
1022 =head2 NEWmodbilbioframework
1024 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1035 my ( $dbh, $bibid ) = @_;
1036 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1037 &REALdelbiblio( $dbh, $bibid );
1040 "select biblioitemnumber from biblioitems where biblionumber=?");
1041 $sth->execute($bibid);
1042 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1043 REALdelbiblioitem( $dbh, $biblioitemnumber );
1045 # &MARCdelbiblio( $dbh, $bibid, 0 );
1047 my $record = get_record($bibid);
1048 # z3950_extended_services('update',set_service_options('update'),$record);
1053 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1057 creates an item from a MARC::Record
1064 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1066 # add item in old-DB
1067 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1068 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1069 # needs old biblionumber and biblioitemnumber
1070 $item->{'biblionumber'} = $biblionumber;
1071 $item->{'biblioitemnumber'}=$biblioitemnumber;
1072 $item->{marc} = $record->as_usmarc();
1073 #warn $item->{marc};
1074 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1081 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1092 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1094 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1095 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1097 $olditem->{marc} = $record->as_usmarc();
1098 $olditem->{biblionumber} = $biblionumber;
1099 $olditem->{biblioitemnumber} = $biblioitemnumber;
1101 REALmoditem( $dbh, $olditem );
1107 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1118 my ( $dbh, $bibid, $itemnumber ) = @_;
1119 &REALdelitem( $dbh, $itemnumber );
1120 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1121 # we must now delete the item data from zebra
1125 =head2 REALnewbiblio
1127 $biblionumber = REALnewbiblio($dbh,$biblio);
1131 adds a record in biblio table. Datas are in the hash $biblio.
1138 my ( $dbh, $biblio ) = @_;
1140 $dbh->do('lock tables biblio WRITE');
1141 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1143 my $data = $sth->fetchrow_arrayref;
1144 my $bibnum = $$data[0] + 1;
1147 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1150 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1151 serial=?, seriestitle=?, notes=?, abstract=?,
1155 $bibnum, $biblio->{'title'},
1156 $biblio->{'author'}, $biblio->{'copyrightdate'},
1157 $biblio->{'serial'}, $biblio->{'seriestitle'},
1158 $biblio->{'notes'}, $biblio->{'abstract'},
1159 $biblio->{'unititle'}
1163 $dbh->do('unlock tables');
1167 =head2 REALmodbiblio
1169 $biblionumber = REALmodbiblio($dbh,$biblio);
1173 modify a record in biblio table. Datas are in the hash $biblio.
1180 my ( $dbh, $biblio ) = @_;
1181 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1182 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1183 where biblionumber = ?"
1186 $biblio->{'title'}, $biblio->{'author'},
1187 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1188 $biblio->{'seriestitle'}, $biblio->{'serial'},
1189 $biblio->{'unititle'}, $biblio->{'notes'},
1190 $biblio->{frameworkcode},
1191 $biblio->{'biblionumber'}
1194 return ( $biblio->{'biblionumber'} );
1197 =head2 REALmodsubtitle
1199 REALmodsubtitle($dbh,$bibnum,$subtitle);
1203 modify subtitles in bibliosubtitle table.
1209 sub REALmodsubtitle {
1210 my ( $dbh, $bibnum, $subtitle ) = @_;
1213 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1214 $sth->execute( $subtitle, $bibnum );
1218 =head2 REALmodaddauthor
1220 REALmodaddauthor($dbh,$bibnum,$author);
1224 adds or modify additional authors
1225 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1231 sub REALmodaddauthor {
1232 my ( $dbh, $bibnum, @authors ) = @_;
1234 # my $dbh = C4Connect;
1236 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1238 $sth->execute($bibnum);
1240 foreach my $author (@authors) {
1241 if ( $author ne '' ) {
1244 "Insert into additionalauthors set author = ?, biblionumber = ?"
1247 $sth->execute( $author, $bibnum );
1252 } # sub modaddauthor
1254 =head2 REALmodsubject
1256 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1260 modify/adds subjects
1265 sub REALmodsubject {
1266 my ( $dbh, $bibnum, $force, @subject ) = @_;
1268 # my $dbh = C4Connect;
1269 my $count = @subject;
1271 for ( my $i = 0 ; $i < $count ; $i++ ) {
1272 $subject[$i] =~ s/^ //g;
1273 $subject[$i] =~ s/ $//g;
1276 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1278 $sth->execute( $subject[$i] );
1280 if ( my $data = $sth->fetchrow_hashref ) {
1283 if ( $force eq $subject[$i] || $force == 1 ) {
1285 # subject not in aut, chosen to force anway
1286 # so insert into cataloguentry so its in auth file
1289 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1292 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1297 "$subject[$i]\n does not exist in the subject authority file";
1300 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1302 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1304 while ( my $data = $sth2->fetchrow_hashref ) {
1305 $error .= "<br>$data->{'catalogueentry'}";
1314 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1315 $sth->execute($bibnum);
1319 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1321 foreach $query (@subject) {
1322 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1331 =head2 REALmodbiblioitem
1333 REALmodbiblioitem($dbh, $biblioitem);
1342 sub REALmodbiblioitem {
1343 my ( $dbh, $biblioitem ) = @_;
1346 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1347 itemtype=?, url=?, isbn=?, issn=?,
1348 publishercode=?, publicationyear=?, classification=?, dewey=?,
1349 subclass=?, illus=?, pages=?, volumeddesc=?,
1350 notes=?, size=?, place=?, marc=?,
1352 where biblioitemnumber=?");
1353 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1354 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1355 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1356 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1357 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1358 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1360 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1362 z3950_extended_services('update',set_service_options('update'),$record);
1365 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1368 =head2 REALnewbiblioitem
1370 REALnewbiblioitem($dbh,$biblioitem);
1374 adds a biblioitem ($biblioitem is a hash with the values)
1380 sub REALnewbiblioitem {
1381 my ( $dbh, $biblioitem ) = @_;
1383 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1384 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1386 my $biblioitemnumber;
1389 $data = $sth->fetchrow_arrayref;
1390 $biblioitemnumber = $$data[0] + 1;
1392 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1393 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1394 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1395 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1396 my $field=$record->field($biblioitemnumberfield);
1397 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1398 $biblioitem->{marc} = $record->as_usmarc();
1399 $biblioitem->{marcxml} = $record->as_xml();
1401 $sth = $dbh->prepare( "insert into biblioitems set
1402 biblioitemnumber = ?, biblionumber = ?,
1403 volume = ?, number = ?,
1404 classification = ?, itemtype = ?,
1406 issn = ?, dewey = ?,
1407 subclass = ?, publicationyear = ?,
1408 publishercode = ?, volumedate = ?,
1409 volumeddesc = ?, illus = ?,
1410 pages = ?, notes = ?,
1412 marc = ?, place = ?,
1416 $biblioitemnumber, $biblioitem->{'biblionumber'},
1417 $biblioitem->{'volume'}, $biblioitem->{'number'},
1418 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1419 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1420 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1421 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1422 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1423 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1424 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1425 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1426 $biblioitem->{'marc'}, $biblioitem->{'place'},
1427 $biblioitem->{marcxml},
1429 $dbh->do("unlock tables");
1430 z3950_extended_services('update',set_service_options('update'),$record);
1431 return ($biblioitemnumber);
1434 =head2 REALnewsubtitle
1436 REALnewsubtitle($dbh,$bibnum,$subtitle);
1440 create a new subtitle
1445 sub REALnewsubtitle {
1446 my ( $dbh, $bibnum, $subtitle ) = @_;
1449 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1450 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1456 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1460 create a item. $item is a hash and $barcode the barcode.
1467 my ( $dbh, $item, $barcode ) = @_;
1469 # warn "OLDNEWITEMS";
1471 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1472 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1477 $data = $sth->fetchrow_hashref;
1478 $itemnumber = $data->{'max(itemnumber)'} + 1;
1480 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1481 if ( $item->{'loan'} ) {
1482 $item->{'notforloan'} = $item->{'loan'};
1484 $item->{'biblioitemnumber'} = 1;
1485 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1486 if ( $item->{'dateaccessioned'} ) {
1487 $sth = $dbh->prepare( "Insert into items set
1488 itemnumber = ?, biblionumber = ?,
1489 multivolumepart = ?,
1490 biblioitemnumber = ?, barcode = ?,
1491 booksellerid = ?, dateaccessioned = ?,
1492 homebranch = ?, holdingbranch = ?,
1493 price = ?, replacementprice = ?,
1494 replacementpricedate = NOW(), datelastseen = NOW(),
1495 multivolume = ?, stack = ?,
1496 itemlost = ?, wthdrawn = ?,
1497 paidfor = ?, itemnotes = ?,
1498 itemcallnumber =?, notforloan = ?,
1503 $itemnumber, $item->{'biblionumber'},
1504 $item->{'multivolumepart'},
1505 $item->{'biblioitemnumber'},$item->{barcode},
1506 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1507 $item->{'homebranch'}, $item->{'holdingbranch'},
1508 $item->{'price'}, $item->{'replacementprice'},
1509 $item->{multivolume}, $item->{stack},
1510 $item->{itemlost}, $item->{wthdrawn},
1511 $item->{paidfor}, $item->{'itemnotes'},
1512 $item->{'itemcallnumber'}, $item->{'notforloan'},
1515 if ( defined $sth->errstr ) {
1516 $error .= $sth->errstr;
1520 $sth = $dbh->prepare( "Insert into items set
1521 itemnumber = ?, biblionumber = ?,
1522 multivolumepart = ?,
1523 biblioitemnumber = ?, barcode = ?,
1524 booksellerid = ?, dateaccessioned = NOW(),
1525 homebranch = ?, holdingbranch = ?,
1526 price = ?, replacementprice = ?,
1527 replacementpricedate = NOW(), datelastseen = NOW(),
1528 multivolume = ?, stack = ?,
1529 itemlost = ?, wthdrawn = ?,
1530 paidfor = ?, itemnotes = ?,
1531 itemcallnumber =?, notforloan = ?,
1536 $itemnumber, $item->{'biblionumber'},
1537 $item->{'multivolumepart'},
1538 $item->{'biblioitemnumber'},$item->{barcode},
1539 $item->{'booksellerid'},
1540 $item->{'homebranch'}, $item->{'holdingbranch'},
1541 $item->{'price'}, $item->{'replacementprice'},
1542 $item->{multivolume}, $item->{stack},
1543 $item->{itemlost}, $item->{wthdrawn},
1544 $item->{paidfor}, $item->{'itemnotes'},
1545 $item->{'itemcallnumber'}, $item->{'notforloan'},
1548 if ( defined $sth->errstr ) {
1549 $error .= $sth->errstr;
1552 # item stored, now, deal with the marc part...
1553 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1554 where biblio.biblionumber=biblioitems.biblionumber and
1555 biblio.biblionumber=?");
1556 $sth->execute($item->{biblionumber});
1557 if ( defined $sth->errstr ) {
1558 $error .= $sth->errstr;
1560 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1561 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1562 my $record = MARC::File::USMARC::decode($rawmarc);
1563 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1564 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1565 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1567 #warn $itemnumberfield;
1568 #warn $itemrecord->field($itemnumberfield);
1569 my $itemfield = $itemrecord->field($itemnumberfield);
1570 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1571 $record->insert_grouped_field($itemfield);
1572 # save the record into biblioitem
1573 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1574 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1575 if ( defined $sth->errstr ) {
1576 $error .= $sth->errstr;
1578 z3950_extended_services('update',set_service_options('update'),$record);
1579 $dbh->do('unlock tables');
1580 return ( $itemnumber, $error );
1583 =head2 REALmoditem($dbh,$item);
1594 my ( $dbh, $item ) = @_;
1595 $item->{'bibitemnum'} = 1;
1597 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1598 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1599 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1601 $item->{'barcode'}, $item->{'itemnotes'},
1602 $item->{'itemcallnumber'}, $item->{'notforloan'},
1603 $item->{'location'}, $item->{multivolumepart},
1604 $item->{multivolume}, $item->{stack},
1607 if ( $item->{'lost'} ne '' ) {
1608 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1609 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1610 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1612 $item->{'bibitemnum'}, $item->{'barcode'},
1613 $item->{'itemnotes'}, $item->{'homebranch'},
1614 $item->{'lost'}, $item->{'wthdrawn'},
1615 $item->{'itemcallnumber'}, $item->{'notforloan'},
1616 $item->{'location'}, $item->{multivolumepart},
1617 $item->{multivolume}, $item->{stack},
1620 if ($item->{homebranch}) {
1621 $query.=",homebranch=?";
1622 push @bind, $item->{homebranch};
1624 if ($item->{holdingbranch}) {
1625 $query.=",holdingbranch=?";
1626 push @bind, $item->{holdingbranch};
1629 $query.=" where itemnumber=?";
1630 push @bind,$item->{'itemnum'};
1631 if ( $item->{'replacement'} ne '' ) {
1632 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1634 my $sth = $dbh->prepare($query);
1635 $sth->execute(@bind);
1637 # item stored, now, deal with the marc part...
1638 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1639 where biblio.biblionumber=biblioitems.biblionumber and
1640 biblio.biblionumber=? and
1641 biblioitems.biblioitemnumber=?");
1642 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1643 if ( defined $sth->errstr ) {
1644 $error .= $sth->errstr;
1646 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1647 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1648 my $record = MARC::File::USMARC::decode($rawmarc);
1649 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1650 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1651 # prepare the new item record
1652 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1653 my $itemfield = $itemrecord->field($itemnumberfield);
1654 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1655 # parse all fields fields from the complete record
1656 foreach ($record->field($itemnumberfield)) {
1657 # when the previous field is found, replace by the new one
1658 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1659 $_->replace_with($itemfield);
1662 # $record->insert_grouped_field($itemfield);
1663 # save the record into biblioitem
1664 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1665 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1666 z3950_extended_services('update',set_service_options('update'),$record);
1667 if ( defined $sth->errstr ) {
1668 $error .= $sth->errstr;
1670 $dbh->do('unlock tables');
1674 =head2 REALdelitem($dbh,$itemnum);
1685 my ( $dbh, $itemnum ) = @_;
1687 # my $dbh=C4Connect;
1688 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1689 $sth->execute($itemnum);
1690 my $data = $sth->fetchrow_hashref;
1692 my $query = "Insert into deleteditems set ";
1694 foreach my $temp ( keys %$data ) {
1695 $query .= "$temp = ?,";
1696 push ( @bind, $data->{$temp} );
1701 $sth = $dbh->prepare($query);
1702 $sth->execute(@bind);
1704 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1705 $sth->execute($itemnum);
1711 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1715 deletes a biblioitem
1716 NOTE : not standard sub name. Should be REALdelbiblioitem()
1722 sub REALdelbiblioitem {
1723 my ( $dbh, $biblioitemnumber ) = @_;
1725 # my $dbh = C4Connect;
1726 my $sth = $dbh->prepare( "Select * from biblioitems
1727 where biblioitemnumber = ?"
1731 $sth->execute($biblioitemnumber);
1733 if ( $results = $sth->fetchrow_hashref ) {
1737 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1738 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1739 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1743 $results->{biblioitemnumber}, $results->{biblionumber},
1744 $results->{volume}, $results->{number},
1745 $results->{classification}, $results->{itemtype},
1746 $results->{isbn}, $results->{issn},
1747 $results->{dewey}, $results->{subclass},
1748 $results->{publicationyear}, $results->{publishercode},
1749 $results->{volumedate}, $results->{volumeddesc},
1750 $results->{timestamp}, $results->{illus},
1751 $results->{pages}, $results->{notes},
1752 $results->{size}, $results->{url},
1756 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1757 $sth2->execute($biblioitemnumber);
1762 # Now delete all the items attached to the biblioitem
1763 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1764 $sth->execute($biblioitemnumber);
1766 while ( my $data = $sth->fetchrow_hashref ) {
1767 my $query = "Insert into deleteditems set ";
1769 foreach my $temp ( keys %$data ) {
1770 $query .= "$temp = ?,";
1771 push ( @bind, $data->{$temp} );
1774 my $sth2 = $dbh->prepare($query);
1775 $sth2->execute(@bind);
1778 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1779 $sth->execute($biblioitemnumber);
1783 } # sub deletebiblioitem
1785 =head2 REALdelbiblio($dbh,$biblio);
1796 my ( $dbh, $biblio ) = @_;
1797 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1798 $sth->execute($biblio);
1799 if ( my $data = $sth->fetchrow_hashref ) {
1801 my $query = "Insert into deletedbiblio set ";
1803 foreach my $temp ( keys %$data ) {
1804 $query .= "$temp = ?,";
1805 push ( @bind, $data->{$temp} );
1808 #replacing the last , by ",?)"
1810 $sth = $dbh->prepare($query);
1811 $sth->execute(@bind);
1813 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1814 $sth->execute($biblio);
1822 $number = itemcount($biblio);
1826 returns the number of items attached to a biblio
1834 my $dbh = C4::Context->dbh;
1837 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1838 $sth->execute($biblio);
1839 my $data = $sth->fetchrow_hashref;
1841 return ( $data->{'count(*)'} );
1846 $biblionumber = newbiblio($biblio);
1850 create a biblio. The parameter is a hash
1858 my $dbh = C4::Context->dbh;
1859 my $bibnum = REALnewbiblio( $dbh, $biblio );
1860 # finds new (MARC bibid
1861 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1862 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1863 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1869 $biblionumber = &modbiblio($biblio);
1873 Update a biblio record.
1875 C<$biblio> is a reference-to-hash whose keys are the fields in the
1876 biblio table in the Koha database. All fields must be present, not
1877 just the ones you wish to change.
1879 C<&modbiblio> updates the record defined by
1880 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1882 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1891 my $dbh = C4::Context->dbh;
1892 my $biblionumber=REALmodbiblio($dbh,$biblio);
1893 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1894 # finds new (MARC bibid
1895 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1896 MARCmodbiblio($dbh,$bibid,$record,"",0);
1897 return($biblionumber);
1900 =head2 &modsubtitle($biblionumber, $subtitle);
1904 Sets the subtitle of a book.
1906 C<$biblionumber> is the biblionumber of the book to modify.
1908 C<$subtitle> is the new subtitle.
1915 my ( $bibnum, $subtitle ) = @_;
1916 my $dbh = C4::Context->dbh;
1917 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1920 =head2 &modaddauthor($biblionumber, $author);
1924 Replaces all additional authors for the book with biblio number
1925 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1926 C<&modaddauthor> deletes all additional authors.
1933 my ( $bibnum, @authors ) = @_;
1934 my $dbh = C4::Context->dbh;
1935 &REALmodaddauthor( $dbh, $bibnum, @authors );
1936 } # sub modaddauthor
1940 $error = &modsubject($biblionumber, $force, @subjects);
1944 $force - a subject to force
1945 $error - Error message, or undef if successful.
1952 my ( $bibnum, $force, @subject ) = @_;
1953 my $dbh = C4::Context->dbh;
1954 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1956 # When MARC is off, ensures that the MARC biblio table gets updated with new
1957 # subjects, of course, it deletes the biblio in marc, and then recreates.
1958 # This check is to ensure that no MARC data exists to lose.
1959 # if (C4::Context->preference("MARC") eq '0'){
1960 # warn "in modSUBJECT";
1961 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1962 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1963 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1969 =head2 modbibitem($dbh, $biblioitem);
1973 modify a biblioitem. The parameter is a hash
1980 my ($dbh, $biblioitem) = @_;
1981 #my $dbh = C4::Context->dbh;
1982 &REALmodbiblioitem( $dbh, $biblioitem );
1985 =head2 newbiblioitem
1987 $biblioitemnumber = newbiblioitem($biblioitem)
1991 create a biblioitem, the parameter is a hash
1998 my ($dbh, $biblioitem) = @_;
1999 #my $dbh = C4::Context->dbh;
2000 # add biblio information to the hash
2001 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
2002 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
2003 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
2004 return ($bibitemnum);
2007 =head2 newsubtitle($biblionumber,$subtitle);
2011 insert a subtitle for $biblionumber biblio
2019 my ( $bibnum, $subtitle ) = @_;
2020 my $dbh = C4::Context->dbh;
2021 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2026 $errors = newitems($dbh, $item, @barcodes);
2030 insert items ($item is a hash)
2038 my ( $dbh, $item, @barcodes ) = @_;
2039 #my $dbh = C4::Context->dbh;
2043 foreach my $barcode (@barcodes) {
2044 # add items, one by one for each barcode.
2046 $oneitem->{barcode}= $barcode;
2047 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2048 $oneitem->{marc} = $MARCitem->as_usmarc;
2049 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2050 # $errors .= $error;
2051 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2056 =head2 moditem($dbh,$item);
2060 modify an item ($item is a hash with all item informations)
2068 my ($dbh, $item) = @_;
2069 #my $dbh = C4::Context->dbh;
2070 &REALmoditem( $dbh, $item );
2072 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2074 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2075 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2080 $error = checkitems($count,@barcodes);
2084 check for each @barcode entry that the barcode is not a duplicate
2091 my ( $count, @barcodes ) = @_;
2092 my $dbh = C4::Context->dbh;
2094 my $sth = $dbh->prepare("Select * from items where barcode=?");
2095 for ( my $i = 0 ; $i < $count ; $i++ ) {
2096 $barcodes[$i] = uc $barcodes[$i];
2097 $sth->execute( $barcodes[$i] );
2098 if ( my $data = $sth->fetchrow_hashref ) {
2099 $error .= " Duplicate Barcode: $barcodes[$i]";
2106 =head2 delitem($itemnum);
2110 delete item $itemnum being the item number to delete
2118 my $dbh = C4::Context->dbh;
2119 &REALdelitem( $dbh, $itemnum );
2122 =head2 deletebiblioitem($biblioitemnumber);
2126 delete the biblioitem $biblioitemnumber
2132 sub deletebiblioitem {
2133 my ($biblioitemnumber) = @_;
2134 my $dbh = C4::Context->dbh;
2135 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2136 } # sub deletebiblioitem
2138 =head2 delbiblio($biblionumber)
2142 delete biblio $biblionumber
2150 my $dbh = C4::Context->dbh;
2151 &REALdelbiblio( $dbh, $biblio );
2152 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2153 &MARCdelbiblio( $dbh, $bibid, 0 );
2158 ($count,@results) = getbiblio($biblionumber);
2162 return an array with hash of biblios.
2164 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2171 my ($biblionumber) = @_;
2172 my $dbh = C4::Context->dbh;
2173 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2175 # || die "Cannot prepare $query\n" . $dbh->errstr;
2179 $sth->execute($biblionumber);
2181 # || die "Cannot execute $query\n" . $sth->errstr;
2182 while ( my $data = $sth->fetchrow_hashref ) {
2183 $results[$count] = $data;
2188 return ( $count, @results );
2193 $data = &bibdata($biblionumber, $type);
2195 Returns information about the book with the given biblionumber.
2197 C<$type> is ignored.
2199 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2200 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2203 In addition, C<$data-E<gt>{subject}> is the list of the book's
2204 subjects, separated by C<" , "> (space, comma, space).
2206 If there are multiple biblioitems with the given biblionumber, only
2207 the first one is considered.
2212 my ($bibnum, $type) = @_;
2213 my $dbh = C4::Context->dbh;
2214 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2216 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2217 left join bibliosubtitle on
2218 biblio.biblionumber = bibliosubtitle.biblionumber
2219 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2220 where biblio.biblionumber = ?
2222 $sth->execute($bibnum);
2224 $data = $sth->fetchrow_hashref;
2226 # handle management of repeated subtitle
2227 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2228 $sth->execute($bibnum);
2230 while (my $dat = $sth->fetchrow_hashref){
2232 $line{subtitle} = $dat->{subtitle};
2233 push @subtitles, \%line;
2235 $data->{subtitles} = \@subtitles;
2237 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2238 $sth->execute($bibnum);
2240 while (my $dat = $sth->fetchrow_hashref){
2242 $line{subject} = $dat->{'subject'};
2243 push @subjects, \%line;
2245 $data->{subjects} = \@subjects;
2247 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2248 $sth->execute($bibnum);
2249 while (my $dat = $sth->fetchrow_hashref){
2250 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2252 chop $data->{'additionalauthors'};
2253 chop $data->{'additionalauthors'};
2254 chop $data->{'additionalauthors'};
2259 =head2 getbiblioitem
2261 ($count,@results) = getbiblioitem($biblioitemnumber);
2265 return an array with hash of biblioitemss.
2267 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2274 my ($biblioitemnum) = @_;
2275 my $dbh = C4::Context->dbh;
2276 my $sth = $dbh->prepare( "Select * from biblioitems where
2277 biblioitemnumber = ?"
2282 $sth->execute($biblioitemnum);
2284 while ( my $data = $sth->fetchrow_hashref ) {
2285 $results[$count] = $data;
2290 return ( $count, @results );
2291 } # sub getbiblioitem
2293 =head2 getbiblioitembybiblionumber
2295 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2299 return an array with hash of biblioitems for the given biblionumber.
2305 sub getbiblioitembybiblionumber {
2306 my ($biblionumber) = @_;
2307 my $dbh = C4::Context->dbh;
2308 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2312 $sth->execute($biblionumber);
2314 while ( my $data = $sth->fetchrow_hashref ) {
2315 $results[$count] = $data;
2320 return ( $count, @results );
2323 =head2 getitemsbybiblioitem
2325 ($count,@results) = getitemsbybiblioitem($biblionumber);
2329 returns an array with hash of items
2335 sub getitemsbybiblioitem {
2336 my ($biblioitemnum) = @_;
2337 my $dbh = C4::Context->dbh;
2338 my $sth = $dbh->prepare( "Select * from items, biblio where
2339 biblio.biblionumber = items.biblionumber and biblioitemnumber
2343 # || die "Cannot prepare $query\n" . $dbh->errstr;
2347 $sth->execute($biblioitemnum);
2349 # || die "Cannot execute $query\n" . $sth->errstr;
2350 while ( my $data = $sth->fetchrow_hashref ) {
2351 $results[$count] = $data;
2356 return ( $count, @results );
2357 } # sub getitemsbybiblioitem
2361 @results = &ItemInfo($env, $biblionumber, $type);
2363 Returns information about books with the given biblionumber.
2365 C<$type> may be either C<intra> or anything else. If it is not set to
2366 C<intra>, then the search will exclude lost, very overdue, and
2371 C<&ItemInfo> returns a list of references-to-hash. Each element
2372 contains a number of keys. Most of them are table items from the
2373 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2374 Koha database. Other keys include:
2378 =item C<$data-E<gt>{branchname}>
2380 The name (not the code) of the branch to which the book belongs.
2382 =item C<$data-E<gt>{datelastseen}>
2384 This is simply C<items.datelastseen>, except that while the date is
2385 stored in YYYY-MM-DD format in the database, here it is converted to
2386 DD/MM/YYYY format. A NULL date is returned as C<//>.
2388 =item C<$data-E<gt>{datedue}>
2390 =item C<$data-E<gt>{class}>
2392 This is the concatenation of C<biblioitems.classification>, the book's
2393 Dewey code, and C<biblioitems.subclass>.
2395 =item C<$data-E<gt>{ocount}>
2397 I think this is the number of copies of the book available.
2399 =item C<$data-E<gt>{order}>
2401 If this is set, it is set to C<One Order>.
2408 my ($env,$biblionumber,$type) = @_;
2409 my $dbh = C4::Context->dbh;
2410 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2411 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2412 WHERE items.biblionumber = ?
2413 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2414 AND biblio.biblionumber = items.biblionumber";
2415 $query .= " order by items.dateaccessioned desc";
2416 my $sth=$dbh->prepare($query);
2417 $sth->execute($biblionumber);
2420 while (my $data=$sth->fetchrow_hashref){
2422 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2423 $isth->execute($data->{'itemnumber'});
2424 if (my $idata=$isth->fetchrow_hashref){
2425 $data->{borrowernumber} = $idata->{borrowernumber};
2426 $data->{cardnumber} = $idata->{cardnumber};
2427 $datedue = format_date($idata->{'date_due'});
2429 if ($datedue eq ''){
2430 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2436 #get branch information.....
2437 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2438 $bsth->execute($data->{'holdingbranch'});
2439 if (my $bdata=$bsth->fetchrow_hashref){
2440 $data->{'branchname'} = $bdata->{'branchname'};
2442 my $date=format_date($data->{'datelastseen'});
2443 $data->{'datelastseen'}=$date;
2444 $data->{'datedue'}=$datedue;
2445 # get notforloan complete status if applicable
2446 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2447 $sthnflstatus->execute;
2448 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2449 if ($authorised_valuecode) {
2450 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2451 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2452 my ($lib) = $sthnflstatus->fetchrow;
2453 $data->{notforloan} = $lib;
2464 ($count, @results) = &bibitems($biblionumber);
2466 Given the biblionumber for a book, C<&bibitems> looks up that book's
2467 biblioitems (different publications of the same book, the audio book
2468 and film versions, etc.).
2470 C<$count> is the number of elements in C<@results>.
2472 C<@results> is an array of references-to-hash; the keys are the fields
2473 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2474 addition, C<itemlost> indicates the availability of the item: if it is
2475 "2", then all copies of the item are long overdue; if it is "1", then
2476 all copies are lost; otherwise, there is at least one copy available.
2482 my $dbh = C4::Context->dbh;
2483 my $sth = $dbh->prepare("SELECT biblioitems.*,
2485 MIN(items.itemlost) as itemlost,
2486 MIN(items.dateaccessioned) as dateaccessioned
2487 FROM biblioitems, itemtypes, items
2488 WHERE biblioitems.biblionumber = ?
2489 AND biblioitems.itemtype = itemtypes.itemtype
2490 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2491 GROUP BY items.biblioitemnumber");
2494 $sth->execute($bibnum);
2495 while (my $data = $sth->fetchrow_hashref) {
2496 $results[$count] = $data;
2500 return($count, @results);
2506 $itemdata = &bibitemdata($biblioitemnumber);
2508 Looks up the biblioitem with the given biblioitemnumber. Returns a
2509 reference-to-hash. The keys are the fields from the C<biblio>,
2510 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2511 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2517 my $dbh = C4::Context->dbh;
2518 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");
2521 $sth->execute($bibitem);
2523 $data = $sth->fetchrow_hashref;
2530 =head2 getbibliofromitemnumber
2532 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2534 Looks up the item with the given itemnumber.
2536 C<$env> and C<$dbh> are ignored.
2538 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2539 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2544 sub getbibliofromitemnumber {
2545 my ($env,$dbh,$itemnumber) = @_;
2546 $dbh = C4::Context->dbh;
2547 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2548 where items.itemnumber = ?
2549 and biblio.biblionumber = items.biblionumber
2550 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2552 $sth->execute($itemnumber);
2553 my $data=$sth->fetchrow_hashref;
2560 @barcodes = &barcodes($biblioitemnumber);
2562 Given a biblioitemnumber, looks up the corresponding items.
2564 Returns an array of references-to-hash; the keys are C<barcode> and
2567 The returned items include very overdue items, but not lost ones.
2572 #called from request.pl
2573 my ($biblioitemnumber)=@_;
2574 my $dbh = C4::Context->dbh;
2575 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2576 WHERE biblioitemnumber = ?
2577 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2578 $sth->execute($biblioitemnumber);
2581 while (my $data=$sth->fetchrow_hashref){
2582 $barcodes[$i]=$data;
2592 $item = &itemdata($barcode);
2594 Looks up the item with the given barcode, and returns a
2595 reference-to-hash containing information about that item. The keys of
2596 the hash are the fields from the C<items> and C<biblioitems> tables in
2601 sub get_item_from_barcode {
2603 my $dbh = C4::Context->dbh;
2604 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2605 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2606 $sth->execute($barcode);
2607 my $data=$sth->fetchrow_hashref;
2615 @issues = &itemissues($biblioitemnumber, $biblio);
2617 Looks up information about who has borrowed the bookZ<>(s) with the
2618 given biblioitemnumber.
2620 C<$biblio> is ignored.
2622 C<&itemissues> returns an array of references-to-hash. The keys
2623 include the fields from the C<items> table in the Koha database.
2624 Additional keys include:
2630 If the item is currently on loan, this gives the due date.
2632 If the item is not on loan, then this is either "Available" or
2633 "Cancelled", if the item has been withdrawn.
2637 If the item is currently on loan, this gives the card number of the
2638 patron who currently has the item.
2640 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2642 These give the timestamp for the last three times the item was
2645 =item C<card0>, C<card1>, C<card2>
2647 The card number of the last three patrons who borrowed this item.
2649 =item C<borrower0>, C<borrower1>, C<borrower2>
2651 The borrower number of the last three patrons who borrowed this item.
2658 my ($bibitem, $biblio)=@_;
2659 my $dbh = C4::Context->dbh;
2660 # FIXME - If this function die()s, the script will abort, and the
2661 # user won't get anything; depending on how far the script has
2662 # gotten, the user might get a blank page. It would be much better
2663 # to at least print an error message. The easiest way to do this
2664 # is to set $SIG{__DIE__}.
2665 my $sth = $dbh->prepare("Select * from items where
2666 items.biblioitemnumber = ?")
2667 || die $dbh->errstr;
2671 $sth->execute($bibitem)
2672 || die $sth->errstr;
2674 while (my $data = $sth->fetchrow_hashref) {
2675 # Find out who currently has this item.
2676 # FIXME - Wouldn't it be better to do this as a left join of
2677 # some sort? Currently, this code assumes that if
2678 # fetchrow_hashref() fails, then the book is on the shelf.
2679 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2680 # database server crash), not just because no items match the
2682 my $sth2 = $dbh->prepare("select * from issues,borrowers
2683 where itemnumber = ?
2684 and returndate is NULL
2685 and issues.borrowernumber = borrowers.borrowernumber");
2687 $sth2->execute($data->{'itemnumber'});
2688 if (my $data2 = $sth2->fetchrow_hashref) {
2689 $data->{'date_due'} = $data2->{'date_due'};
2690 $data->{'card'} = $data2->{'cardnumber'};
2691 $data->{'borrower'} = $data2->{'borrowernumber'};
2693 if ($data->{'wthdrawn'} eq '1') {
2694 $data->{'date_due'} = 'Cancelled';
2696 $data->{'date_due'} = 'Available';
2702 # Find the last 3 people who borrowed this item.
2703 $sth2 = $dbh->prepare("select * from issues, borrowers
2704 where itemnumber = ?
2705 and issues.borrowernumber = borrowers.borrowernumber
2706 and returndate is not NULL
2707 order by returndate desc,timestamp desc") || die $dbh->errstr;
2708 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2709 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2710 if (my $data2 = $sth2->fetchrow_hashref) {
2711 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2712 $data->{"card$i2"} = $data2->{'cardnumber'};
2713 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2718 $results[$i] = $data;
2728 ($count, $subjects) = &getsubject($biblionumber);
2730 Looks up the subjects of the book with the given biblionumber. Returns
2731 a two-element list. C<$subjects> is a reference-to-array, where each
2732 element is a subject of the book, and C<$count> is the number of
2733 elements in C<$subjects>.
2739 my $dbh = C4::Context->dbh;
2740 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2741 $sth->execute($bibnum);
2744 while (my $data=$sth->fetchrow_hashref){
2749 return($i,\@results);
2754 ($count, $authors) = &getaddauthor($biblionumber);
2756 Looks up the additional authors for the book with the given
2759 Returns a two-element list. C<$authors> is a reference-to-array, where
2760 each element is an additional author, and C<$count> is the number of
2761 elements in C<$authors>.
2767 my $dbh = C4::Context->dbh;
2768 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2769 $sth->execute($bibnum);
2772 while (my $data=$sth->fetchrow_hashref){
2777 return($i,\@results);
2783 ($count, $subtitles) = &getsubtitle($biblionumber);
2785 Looks up the subtitles for the book with the given biblionumber.
2787 Returns a two-element list. C<$subtitles> is a reference-to-array,
2788 where each element is a subtitle, and C<$count> is the number of
2789 elements in C<$subtitles>.
2795 my $dbh = C4::Context->dbh;
2796 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2797 $sth->execute($bibnum);
2800 while (my $data=$sth->fetchrow_hashref){
2805 return($i,\@results);
2811 ($count, @websites) = &getwebsites($biblionumber);
2813 Looks up the web sites pertaining to the book with the given
2816 C<$count> is the number of elements in C<@websites>.
2818 C<@websites> is an array of references-to-hash; the keys are the
2819 fields from the C<websites> table in the Koha database.
2822 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2823 #(with add / modify / delete subs)
2826 my ($biblionumber) = @_;
2827 my $dbh = C4::Context->dbh;
2828 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2832 $sth->execute($biblionumber);
2833 while (my $data = $sth->fetchrow_hashref) {
2834 # FIXME - The URL scheme shouldn't be stripped off, at least
2835 # not here, since it's part of the URL, and will be useful in
2836 # constructing a link to the site. If you don't want the user
2837 # to see the "http://" part, strip that off when building the
2839 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2841 $results[$count] = $data;
2846 return($count, @results);
2849 =head2 getwebbiblioitems
2851 ($count, @results) = &getwebbiblioitems($biblionumber);
2853 Given a book's biblionumber, looks up the web versions of the book
2854 (biblioitems with itemtype C<WEB>).
2856 C<$count> is the number of items in C<@results>. C<@results> is an
2857 array of references-to-hash; the keys are the items from the
2858 C<biblioitems> table of the Koha database.
2862 sub getwebbiblioitems {
2863 my ($biblionumber) = @_;
2864 my $dbh = C4::Context->dbh;
2865 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2866 and itemtype = 'WEB'");
2870 $sth->execute($biblionumber);
2871 while (my $data = $sth->fetchrow_hashref) {
2872 $data->{'url'} =~ s/^http:\/\///;
2873 $results[$count] = $data;
2878 return($count, @results);
2879 } # sub getwebbiblioitems
2882 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2883 my $NSE = '\x89'; # NSE : Non Sorting Block end
2884 # handles non sorting blocks
2888 s/[ ]{0,1}$NSE/) /gm;
2895 my $dbh = C4::Context->dbh;
2896 my $result = MARCmarc2koha($dbh,$record,'');
2898 my ($biblionumber,$bibid,$title);
2899 # search duplicate on ISBN, easy and fast...
2900 if ($result->{isbn}) {
2901 $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=?");
2902 $sth->execute($result->{'isbn'});
2903 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2904 return $biblionumber,$bibid,$title if ($biblionumber);
2906 # a more complex search : build a request for SearchMarc::catalogsearch()
2907 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2908 # search on biblio.title
2909 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2910 if ($record->field($tag)) {
2911 if ($record->field($tag)->subfields($subfield)) {
2912 push @tags, "'".$tag.$subfield."'";
2913 push @and_or, "and";
2914 push @excluding, "";
2915 push @operator, "contains";
2916 push @value, $record->field($tag)->subfield($subfield);
2917 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2920 # ... and on biblio.author
2921 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2922 if ($record->field($tag)) {
2923 if ($record->field($tag)->subfields($subfield)) {
2924 push @tags, "'".$tag.$subfield."'";
2925 push @and_or, "and";
2926 push @excluding, "";
2927 push @operator, "contains";
2928 push @value, $record->field($tag)->subfield($subfield);
2929 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2932 # ... and on publicationyear.
2933 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2934 if ($record->field($tag)) {
2935 if ($record->field($tag)->subfields($subfield)) {
2936 push @tags, "'".$tag.$subfield."'";
2937 push @and_or, "and";
2938 push @excluding, "";
2939 push @operator, "=";
2940 push @value, $record->field($tag)->subfield($subfield);
2941 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2945 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2946 if ($record->field($tag)) {
2947 if ($record->field($tag)->subfields($subfield)) {
2948 push @tags, "'".$tag.$subfield."'";
2949 push @and_or, "and";
2950 push @excluding, "";
2951 push @operator, "=";
2952 push @value, $record->field($tag)->subfield($subfield);
2953 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2956 # ... and on publisher.
2957 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2958 if ($record->field($tag)) {
2959 if ($record->field($tag)->subfields($subfield)) {
2960 push @tags, "'".$tag.$subfield."'";
2961 push @and_or, "and";
2962 push @excluding, "";
2963 push @operator, "=";
2964 push @value, $record->field($tag)->subfield($subfield);
2965 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2968 # ... and on volume.
2969 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2970 if ($record->field($tag)) {
2971 if ($record->field($tag)->subfields($subfield)) {
2972 push @tags, "'".$tag.$subfield."'";
2973 push @and_or, "and";
2974 push @excluding, "";
2975 push @operator, "=";
2976 push @value, $record->field($tag)->subfield($subfield);
2977 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2981 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2982 # there is at least 1 result => return the 1st one
2984 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2985 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2987 # no result, returns nothing
2994 if(substr($isbn, 0, 1) <=7) {
2995 $seg1 = substr($isbn, 0, 1);
2996 } elsif(substr($isbn, 0, 2) <= 94) {
2997 $seg1 = substr($isbn, 0, 2);
2998 } elsif(substr($isbn, 0, 3) <= 995) {
2999 $seg1 = substr($isbn, 0, 3);
3000 } elsif(substr($isbn, 0, 4) <= 9989) {
3001 $seg1 = substr($isbn, 0, 4);
3003 $seg1 = substr($isbn, 0, 5);
3005 my $x = substr($isbn, length($seg1));
3007 if(substr($x, 0, 2) <= 19) {
3008 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
3009 $seg2 = substr($x, 0, 2);
3010 } elsif(substr($x, 0, 3) <= 699) {
3011 $seg2 = substr($x, 0, 3);
3012 } elsif(substr($x, 0, 4) <= 8399) {
3013 $seg2 = substr($x, 0, 4);
3014 } elsif(substr($x, 0, 5) <= 89999) {
3015 $seg2 = substr($x, 0, 5);
3016 } elsif(substr($x, 0, 6) <= 9499999) {
3017 $seg2 = substr($x, 0, 6);
3019 $seg2 = substr($x, 0, 7);
3021 my $seg3=substr($x,length($seg2));
3022 $seg3=substr($seg3,0,length($seg3)-1) ;
3023 my $seg4 = substr($x, -1, 1);
3024 return "$seg1-$seg2-$seg3-$seg4";
3028 END { } # module clean-up code here (global destructor)
3034 Koha Developement team <info@koha.org>
3036 Paul POULAIN paul.poulain@free.fr
3042 # Revision 1.159 2006/03/07 21:54:47 rangi
3043 # Starting work on deletes
3045 # Revision 1.158 2006/03/06 02:45:41 kados
3046 # Adding fixes to MARC editor to HEAD
3048 # Revision 1.157 2006/03/01 03:07:54 kados
3049 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3051 # Revision 1.155 2006/02/27 01:08:31 kados
3052 # Removing 'our Zconn' from top...
3054 # Revision 1.154 2006/02/26 00:08:20 kados
3055 # moving all $Zconn s to z3950_extended_services (currently, nothing
3058 # Revision 1.153 2006/02/25 22:39:10 kados
3059 # Another purely documentation commit. Just changing formatting to ease
3062 # Revision 1.152 2006/02/25 21:17:20 kados
3063 # Purely documentation change: converted all =head2 entries to use function
3064 # name as title rather than usage as title
3066 # Revision 1.151 2006/02/25 21:02:20 kados
3068 # Further cleanup, convering new routines to 4-chars
3070 # Revision 1.150 2006/02/25 20:49:15 kados
3071 # Better documentation, added warning if serviceType is 'drop' since it's
3072 # not supported in Zebra.
3074 # Revision 1.149 2006/02/25 20:30:32 kados
3075 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3076 # longer necessary. If we need to convert from MARC-8 for display, we should:
3079 # 2. do it with MARC::Charset
3081 # If you still need it, let me know and I'll put it back in.
3083 # Revision 1.148 2006/02/25 19:23:01 kados
3084 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3085 # replaced by z3950_extended_services).
3087 # Revision 1.147 2006/02/25 19:09:59 kados
3088 # readding some lost subs
3090 # Revision 1.145 2006/02/22 01:02:39 kados
3091 # Replacing all calls to zebra_update with calls to
3092 # z3950_extended_services. More work coming, but it's
3095 # Revision 1.144 2006/02/20 14:22:38 kados
3098 # Revision 1.143 2006/02/20 13:26:11 kados
3099 # A new subroutine to handle Z39.50 extended services. You pass it a
3100 # connection object, service type, service options, and a record, and
3101 # it performs the service and handles any exception found.
3103 # Revision 1.142 2006/02/16 20:49:56 kados
3104 # destroy a connection after we're done -- we really should just have one
3105 # connection object and not destroy it until the whole transaction is
3106 # finished -- but this will do for now
3108 # Revision 1.141 2006/02/16 19:47:22 rangi
3109 # Trying to error trap a little more.
3111 # Revision 1.140 2006/02/14 21:36:03 kados
3112 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3113 # also adding diagnostic error if not able to connect to Zebra
3115 # Revision 1.139 2006/02/14 19:53:25 rangi
3116 # Just a little missing my
3118 # Seems to be working great Paul, and I like what you did with zebradb
3120 # Revision 1.138 2006/02/14 11:25:22 tipaul
3121 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3123 # Revision 1.137 2006/02/13 16:34:26 tipaul
3124 # fixing some warnings (perl -w should be quiet)
3126 # Revision 1.136 2006/01/10 17:01:29 tipaul
3127 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3129 # Revision 1.135 2006/01/06 16:39:37 tipaul
3130 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3131 # Seems not to break too many things, but i'm probably wrong here.
3132 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3134 # - removing useless directories (koha-html and koha-plucene)
3136 # Revision 1.134 2006/01/04 15:54:55 tipaul
3137 # utf8 is a : go for beta test in HEAD.
3138 # some explanations :
3139 # - 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.
3140 # - *-top.inc will show the pages in utf8
3141 # - 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.
3142 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3144 # Revision 1.133 2005/12/12 14:25:51 thd
3147 # Reverse array filled with elements from repeated subfields
3148 # to avoid last to first concatenation of elements in Koha DB.-
3150 # Revision 1.132 2005-10-26 09:12:33 tipaul
3151 # big commit, still breaking things...
3153 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3154 # * code cleaning (cleaning warnings from perl -w) continued
3156 # Revision 1.131 2005/09/22 10:01:45 tipaul
3157 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3159 # Revision 1.130 2005/09/02 14:34:14 tipaul
3160 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3161 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3162 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3164 # Revision 1.129 2005/08/12 13:50:31 tipaul
3165 # removing useless sub declarations
3167 # Revision 1.128 2005/08/11 16:12:47 tipaul
3168 # Playing with the zebra...
3170 # * go to koha cvs home directory
3171 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3172 # * put your zebra.cfg files here & create your database.
3173 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3174 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3177 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3178 # * deletion still not work
3179 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3181 # recordId: (bib1,Local-number)
3185 # elm 090 Local-number -
3186 # elm 090/? Local-number -
3187 # elm 090/?/9 Local-number !:w
3189 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3191 # Revision 1.127 2005/08/11 14:37:32 tipaul
3193 # * removing useless subs
3194 # * removing some subs that are also elsewhere
3195 # * 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)
3197 # Revision 1.126 2005/08/11 09:13:28 tipaul
3198 # just removing useless subs (a lot !!!) for code cleaning
3200 # Revision 1.125 2005/08/11 09:00:07 tipaul
3201 # Ok guys, this time, it seems that item add and modif begin working as expected...
3202 # Still a lot of bugs to fix, of course
3204 # Revision 1.124 2005/08/10 10:21:15 tipaul
3205 # continuing the road to zebra :
3206 # - the biblio add begins to work.
3207 # - the biblio modif begins to work.
3209 # (still without doing anything on zebra)
3210 # (no new change in updatedatabase)
3212 # Revision 1.123 2005/08/09 14:10:28 tipaul
3213 # 1st commit to go to zebra.
3214 # don't update your cvs if you want to have a working head...
3216 # this commit contains :
3217 # * 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...
3218 # * 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.
3219 # * other files : get rid of bibid and use biblionumber instead.
3222 # * does not do anything on zebra yet.
3223 # * if you rename marc_subfield_table, you can't search anymore.
3224 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3225 # * 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 ;-) )
3227 # 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
3228 # 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.
3230 # tipaul cutted previous commit notes