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,$action,$recordId) = @_;
233 if ($serviceType eq 'update') {
235 $serviceOptions->{ 'action' } = $action;
237 $serviceOptions->{ 'action' } = 'specialUpdate';
240 $serviceOptions->{'recordIdNumber'} = $recordId;
243 # FIXME: This needs to be an OID ... if we ever need 'syntax' this sub will need to change
244 # $serviceOptions->{ 'syntax' } = ''; #zebra doesn't support syntaxes other than xml
247 if ($serviceType eq 'commit') {
251 if ($serviceType eq 'create') {
254 if ($serviceType eq 'drop') {
255 die "ERROR: 'drop' not currently supported (by Zebra)";
259 return $serviceOptions;
264 my $xmlrecord = marc2xml($record);
266 Convert from MARC to XML. Note that MARC::File::XML will automatically encode from MARC-8 to UTF-8 as of version .8
268 C<$record> a MARC record
275 eval { $xmlrecord=$record->as_xml() };
276 #TODO: better error handling here
278 warn "ERROR: I suspect a badly formatted MARC record";
283 =head2 MARCgettagslib
285 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
289 2nd param is 1 for liblibrarian and 0 for libopac
290 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
292 returns a hash with all values for all fields and subfields for a given MARC framework :
293 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
295 ->{mandatory} = $mandatory;
296 ->{repeatable} = $repeatable;
297 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
299 ->{mandatory} = $mandatory;
300 ->{repeatable} = $repeatable;
301 ->{authorised_value} = $authorised_value;
302 ->{authtypecode} = $authtypecode;
303 ->{value_builder} = $value_builder;
304 ->{kohafield} = $kohafield;
305 ->{seealso} = $seealso;
306 ->{hidden} = $hidden;
315 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
316 $frameworkcode = "" unless $frameworkcode;
317 $forlibrarian = 1 unless $forlibrarian;
319 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
321 # check that framework exists
324 "select count(*) from marc_tag_structure where frameworkcode=?");
325 $sth->execute($frameworkcode);
326 my ($total) = $sth->fetchrow;
327 $frameworkcode = "" unless ( $total > 0 );
330 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
332 $sth->execute($frameworkcode);
333 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
335 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
336 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
337 $res->{$tag}->{tab} = ""; # XXX
338 $res->{$tag}->{mandatory} = $mandatory;
339 $res->{$tag}->{repeatable} = $repeatable;
344 "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"
346 $sth->execute($frameworkcode);
349 my $authorised_value;
359 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
360 $mandatory, $repeatable, $authorised_value, $authtypecode,
361 $value_builder, $kohafield, $seealso, $hidden,
366 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
367 $res->{$tag}->{$subfield}->{tab} = $tab;
368 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
369 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
370 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
371 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
372 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
373 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
374 $res->{$tag}->{$subfield}->{seealso} = $seealso;
375 $res->{$tag}->{$subfield}->{hidden} = $hidden;
376 $res->{$tag}->{$subfield}->{isurl} = $isurl;
377 $res->{$tag}->{$subfield}->{link} = $link;
382 =head2 MARCfind_marc_from_kohafield
384 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
388 finds MARC tag and subfield for a given kohafield
389 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
395 sub MARCfind_marc_from_kohafield {
396 my ( $dbh, $kohafield,$frameworkcode ) = @_;
397 return 0, 0 unless $kohafield;
398 $frameworkcode='' unless $frameworkcode;
399 my $relations = C4::Context->marcfromkohafield;
400 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
405 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
409 Returns a MARC::Record for the biblio $biblionumber.
415 # Returns MARC::Record of the biblio passed in parameter.
416 my ( $dbh, $biblionumber ) = @_;
417 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
418 $sth->execute($biblionumber);
419 my ($marc) = $sth->fetchrow;
420 my $record = MARC::Record::new_from_usmarc($marc);
426 $XML = &XMLgetbiblio($dbh,$biblionumber);
430 Returns a raw XML for the biblio $biblionumber.
436 # Returns MARC::Record of the biblio passed in parameter.
437 my ( $dbh, $biblionumber ) = @_;
438 my $sth = $dbh->prepare('select marcxml,marc from biblioitems where biblionumber=?');
439 $sth->execute($biblionumber);
440 my ($XML,$marc) = $sth->fetchrow;
441 # my $record =MARC::Record::new_from_usmarc($marc);
442 # warn "MARC : \n*-************************\n".$record->as_xml."\n*-************************\n";
448 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
452 Returns a MARC::Record with all items of biblio # $biblionumber
460 my ( $dbh, $biblionumber, $itemnumber ) = @_;
461 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
462 # get the complete MARC record
463 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
464 $sth->execute($biblionumber);
465 my ($rawmarc) = $sth->fetchrow;
466 my $record = MARC::File::USMARC::decode($rawmarc);
467 # now, find the relevant itemnumber
468 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
469 # prepare the new item record
470 my $itemrecord = MARC::Record->new();
471 # parse all fields fields from the complete record
472 foreach ($record->field($itemnumberfield)) {
473 # when the item field is found, save it
474 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
475 $itemrecord->append_fields($_);
482 =head2 find_biblioitemnumber
484 my $biblioitemnumber = find_biblioitemnumber($dbh,$biblionumber);
488 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
489 This sub is useless when MARC=OFF
494 sub find_biblioitemnumber {
495 my ( $dbh, $biblionumber ) = @_;
496 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
497 $sth->execute($biblionumber);
498 my ($biblioitemnumber) = $sth->fetchrow;
499 return $biblioitemnumber;
502 =head2 MARCfind_frameworkcode
504 my $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
508 returns the framework of a given biblio
514 sub MARCfind_frameworkcode {
515 my ( $dbh, $biblionumber ) = @_;
516 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
517 $sth->execute($biblionumber);
518 my ($frameworkcode) = $sth->fetchrow;
519 return $frameworkcode;
522 =head2 MARCkoha2marcBiblio
524 $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibliohash);
528 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
529 all entries of the hash are transformed into their matching MARC field/subfield.
535 sub MARCkoha2marcBiblio {
537 # this function builds partial MARC::Record from the old koha-DB fields
538 my ( $dbh, $bibliohash ) = @_;
539 # we don't have biblio entries in the hash, so we add them first
540 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
541 $sth->execute($bibliohash->{biblionumber});
542 my $biblio = $sth->fetchrow_hashref;
543 foreach (keys %$biblio) {
544 $bibliohash->{$_}=$biblio->{$_};
546 $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
547 my $record = MARC::Record->new();
548 foreach ( keys %$bibliohash ) {
549 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
550 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $_, $bibliohash->{$_}, '') if $bibliohash->{$_};
553 # other fields => additional authors, subjects, subtitles
554 my $sth2 = $dbh->prepare(" SELECT author FROM additionalauthors WHERE biblionumber=?");
555 $sth2->execute($bibliohash->{biblionumber});
556 while ( my $row = $sth2->fetchrow_hashref ) {
557 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author", $bibliohash->{'author'},'' );
559 $sth2 = $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
560 $sth2->execute($bibliohash->{biblionumber});
561 while ( my $row = $sth2->fetchrow_hashref ) {
562 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject", $row->{'subject'},'' );
564 $sth2 = $dbh->prepare(" SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
565 $sth2->execute($bibliohash->{biblionumber});
566 while ( my $row = $sth2->fetchrow_hashref ) {
567 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle", $row->{'subtitle'},'' );
573 =head2 MARCkoha2marcItem
575 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
577 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
578 all entries of the hash are transformed into their matching MARC field/subfield.
586 sub MARCkoha2marcItem {
588 # this function builds partial MARC::Record from the old koha-DB fields
589 my ( $dbh, $item ) = @_;
591 # my $dbh=&C4Connect;
592 my $sth = $dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
593 my $record = MARC::Record->new();
595 foreach( keys %$item ) {
597 &MARCkoha2marcOnefield( $sth, $record, "items." . $_,
604 =head2 MARCkoha2marcOnefield
608 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
614 sub MARCkoha2marcOnefield {
615 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
618 $sth->execute($frameworkcode,$kohafieldname);
619 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
620 if ( $record->field($tagfield) ) {
621 my $tag = $record->field($tagfield);
623 $tag->add_subfields( $tagsubfield, $value );
624 $record->delete_field($tag);
625 $record->add_fields($tag);
629 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
636 $XMLrecord = MARChtml2xml($rtags,$rsubfields,$rvalues,$indicator,$ind_tag);
638 transforms the parameters (coming from HTML form) into a MARC::File::XML
639 object. parameters with r are references to arrays
643 my ($tags,$subfields,$values,$indicator,$ind_tag) = @_;
645 my $xml= MARC::File::XML::header();
650 for (my $i=0;$i<=@$tags;$i++){
652 if ((@$tags[$i] ne $prevtag)){
653 $j++ unless (@$tags[$i] eq "");
654 warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
657 $xml.="</datafield>\n";
661 if (@$values[$i] ne "") {
663 if (@$tags[$i] eq "000") {
664 $xml.="<leader>@$values[$i]</leader>\n";
666 # rest of the fixed fields
667 } elsif (@$tags[$i] < 10) {
668 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
672 my $ind1 = substr(@$indicator[$j],0,1);
673 my $ind2 = substr(@$indicator[$j],1,1);
674 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
675 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
681 if (@$values[$i] eq "") {
685 my $ind1 = substr(@$indicator[$j],0,1);
686 my $ind2 = substr(@$indicator[$j],1,1);
687 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
690 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
694 $prevtag = @$tags[$i];
696 $xml.= MARC::File::XML::footer();
702 $MARCrecord = MARChtml2marc($dbh,$rtags,$rsubfields,$rvalues,%indicators);
706 transforms the parameters (coming from HTML form) into a MARC::Record
707 parameters with r are references to arrays.
709 FIXME : should be improved for 3.0, to avoid having 4 differents arrays
716 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
718 my $record = MARC::Record->new();
719 # my %subfieldlist=();
720 my $prevvalue; # if tag <10
721 my $field; # if tag >=10
722 for (my $i=0; $i< @$rtags; $i++) {
723 next unless @$rvalues[$i];
724 # rebuild MARC::Record
725 # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
726 if (@$rtags[$i] ne $prevtag) {
729 if ($prevtag ne '000') {
730 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
732 $record->leader($prevvalue);
737 $record->add_fields($field);
740 $indicators{@$rtags[$i]}.=' ';
741 if (@$rtags[$i] <10) {
742 $prevvalue= @$rvalues[$i];
746 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
747 # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
749 $prevtag = @$rtags[$i];
751 if (@$rtags[$i] <10) {
752 $prevvalue=@$rvalues[$i];
754 if (length(@$rvalues[$i])>0) {
755 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
756 # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
759 $prevtag= @$rtags[$i];
762 # the last has not been included inside the loop... do it now !
763 $record->add_fields($field) if $field;
764 # warn "HTML2MARC=".$record->as_formatted;
771 $hash = &MARCmarc2koha($dbh,$MARCRecord);
775 builds a hash with old-db datas from a MARC::Record
782 my ($dbh,$record,$frameworkcode) = @_;
783 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
785 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
788 while (($field)=$sth2->fetchrow) {
789 # warn "biblio.".$field;
790 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
792 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
794 while (($field)=$sth2->fetchrow) {
795 if ($field eq 'notes') { $field = 'bnotes'; }
796 # warn "biblioitems".$field;
797 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
799 $sth2=$dbh->prepare("SHOW COLUMNS from items");
801 while (($field)=$sth2->fetchrow) {
802 # warn "items".$field;
803 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
805 # additional authors : specific
806 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
807 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
808 # modify copyrightdate to keep only the 1st year found
809 my $temp = $result->{'copyrightdate'};
811 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
813 $result->{'copyrightdate'} = $1;
814 } else { # if no cYYYY, get the 1st date.
815 $temp =~ m/(\d\d\d\d)/;
816 $result->{'copyrightdate'} = $1;
819 # modify publicationyear to keep only the 1st year found
820 $temp = $result->{'publicationyear'};
821 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
823 $result->{'publicationyear'} = $1;
824 } else { # if no cYYYY, get the 1st date.
825 $temp =~ m/(\d\d\d\d)/;
826 $result->{'publicationyear'} = $1;
831 sub MARCmarc2kohaOneField {
833 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
834 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
835 # warn "kohatable / $kohafield / $result / ";
839 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
840 foreach my $field ( $record->field($tagfield) ) {
841 if ($field->tag()<10) {
842 if ($result->{$kohafield}) {
843 # Reverse array filled with elements from repeated subfields
844 # from first to last to avoid last to first concatenation of
845 # elements in Koha DB. -- thd.
846 $result->{$kohafield} .= " | ".reverse($field->data());
848 $result->{$kohafield} = $field->data();
851 if ( $field->subfields ) {
852 my @subfields = $field->subfields();
853 foreach my $subfieldcount ( 0 .. $#subfields ) {
854 if ($subfields[$subfieldcount][0] eq $subfield) {
855 if ( $result->{$kohafield} ) {
856 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
859 $result->{$kohafield} = $subfields[$subfieldcount][1];
866 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
872 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
876 creates a biblio from a MARC::Record.
883 my ( $dbh,$record,$frameworkcode ) = @_;
885 my $biblioitemnumber;
886 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
887 $olddata->{frameworkcode} = $frameworkcode;
888 $biblionumber = REALnewbiblio( $dbh, $olddata );
889 $olddata->{biblionumber} = $biblionumber;
890 # add biblionumber into the MARC record (it's the ID for zebra)
891 my ( $tagfield, $tagsubfield ) =
892 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
896 $newfield = MARC::Field->new(
897 $tagfield, $biblionumber,
900 $newfield = MARC::Field->new(
901 $tagfield, '', '', "$tagsubfield" => $biblionumber,
904 # drop old field (just in case it already exist and create new one...
905 my $old_field = $record->field($tagfield);
906 $record->delete_field($old_field);
907 $record->add_fields($newfield);
909 #create the marc entry, that stores the rax marc record in Koha 3.0
910 $olddata->{marc} = $record->as_usmarc();
911 $olddata->{marcxml} = $record->as_xml();
912 # and create biblioitem, that's all folks !
913 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
915 # search subtiles, addiauthors and subjects
916 ( $tagfield, $tagsubfield ) =
917 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
918 my @addiauthfields = $record->field($tagfield);
919 foreach my $addiauthfield (@addiauthfields) {
920 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
921 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
922 REALmodaddauthor( $dbh, $biblionumber,
923 $addiauthsubfields[$subfieldcount] );
926 ( $tagfield, $tagsubfield ) =
927 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
928 my @subtitlefields = $record->field($tagfield);
929 foreach my $subtitlefield (@subtitlefields) {
930 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
931 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
932 REALnewsubtitle( $dbh, $biblionumber,
933 $subtitlesubfields[$subfieldcount] );
936 ( $tagfield, $tagsubfield ) =
937 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
938 my @subj = $record->field($tagfield);
940 foreach my $subject (@subj) {
941 my @subjsubfield = $subject->subfield($tagsubfield);
942 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
943 push @subjects, $subjsubfield[$subfieldcount];
946 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
947 return ( $biblionumber, $biblioitemnumber );
950 =head2 NEWmodbilbioframework
952 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
956 modify the framework of a biblio
962 sub NEWmodbiblioframework {
963 my ($dbh,$biblionumber,$frameworkcode) =@_;
964 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
965 $sth->execute($frameworkcode,$biblionumber);
971 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
975 modify a biblio (MARC=ON)
982 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
983 $frameworkcode="" unless $frameworkcode;
984 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
985 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
987 $oldbiblio->{frameworkcode} = $frameworkcode;
988 #create the marc entry, that stores the rax marc record in Koha 3.0
989 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
990 $oldbiblio->{marc} = $record->as_usmarc();
991 $oldbiblio->{marcxml} = $record->as_xml();
992 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
993 REALmodbiblio($dbh,$oldbiblio);
994 REALmodbiblioitem($dbh,$oldbiblio);
995 # now, modify addi authors, subject, addititles.
996 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
997 my @addiauthfields = $record->field($tagfield);
998 foreach my $addiauthfield (@addiauthfields) {
999 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
1000 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
1001 foreach my $subfieldcount (0..$#addiauthsubfields) {
1002 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
1005 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
1006 my @subtitlefields = $record->field($tagfield);
1007 foreach my $subtitlefield (@subtitlefields) {
1008 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1009 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
1011 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
1012 foreach my $subfieldcount (0..$#subtitlesubfields) {
1013 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1014 REALnewsubtitle($dbh,$biblionumber,$subtit);
1018 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1019 my @subj = $record->field($tagfield);
1021 foreach my $subject (@subj) {
1022 my @subjsubfield = $subject->subfield($tagsubfield);
1023 foreach my $subfieldcount (0..$#subjsubfield) {
1024 push @subjects,$subjsubfield[$subfieldcount];
1027 REALmodsubject($dbh,$biblionumber,1,@subjects);
1031 =head2 NEWmodbilbioframework
1033 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
1044 my ( $dbh, $bibid ) = @_;
1045 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1046 &REALdelbiblio( $dbh, $bibid );
1049 "select biblioitemnumber from biblioitems where biblionumber=?");
1050 $sth->execute($bibid);
1051 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1052 REALdelbiblioitem( $dbh, $biblioitemnumber );
1054 # &MARCdelbiblio( $dbh, $bibid, 0 );
1056 my $record = get_record($bibid);
1057 # z3950_extended_services('update',set_service_options('update'),$record);
1062 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1066 creates an item from a MARC::Record
1073 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1075 # add item in old-DB
1076 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1077 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1078 # needs old biblionumber and biblioitemnumber
1079 $item->{'biblionumber'} = $biblionumber;
1080 $item->{'biblioitemnumber'}=$biblioitemnumber;
1081 $item->{marc} = $record->as_usmarc();
1082 #warn $item->{marc};
1083 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1090 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1101 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1103 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1104 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1106 $olditem->{marc} = $record->as_usmarc();
1107 $olditem->{biblionumber} = $biblionumber;
1108 $olditem->{biblioitemnumber} = $biblioitemnumber;
1110 REALmoditem( $dbh, $olditem );
1116 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1127 my ( $dbh, $bibid, $itemnumber ) = @_;
1128 &REALdelitem( $dbh, $itemnumber );
1129 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1130 # we must now delete the item data from zebra
1134 =head2 REALnewbiblio
1136 $biblionumber = REALnewbiblio($dbh,$biblio);
1140 adds a record in biblio table. Datas are in the hash $biblio.
1147 my ( $dbh, $biblio ) = @_;
1149 $dbh->do('lock tables biblio WRITE');
1150 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1152 my $data = $sth->fetchrow_arrayref;
1153 my $bibnum = $$data[0] + 1;
1156 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1159 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1160 serial=?, seriestitle=?, notes=?, abstract=?,
1164 $bibnum, $biblio->{'title'},
1165 $biblio->{'author'}, $biblio->{'copyrightdate'},
1166 $biblio->{'serial'}, $biblio->{'seriestitle'},
1167 $biblio->{'notes'}, $biblio->{'abstract'},
1168 $biblio->{'unititle'}
1172 $dbh->do('unlock tables');
1176 =head2 REALmodbiblio
1178 $biblionumber = REALmodbiblio($dbh,$biblio);
1182 modify a record in biblio table. Datas are in the hash $biblio.
1189 my ( $dbh, $biblio ) = @_;
1190 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1191 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1192 where biblionumber = ?"
1195 $biblio->{'title'}, $biblio->{'author'},
1196 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1197 $biblio->{'seriestitle'}, $biblio->{'serial'},
1198 $biblio->{'unititle'}, $biblio->{'notes'},
1199 $biblio->{frameworkcode},
1200 $biblio->{'biblionumber'}
1203 return ( $biblio->{'biblionumber'} );
1206 =head2 REALmodsubtitle
1208 REALmodsubtitle($dbh,$bibnum,$subtitle);
1212 modify subtitles in bibliosubtitle table.
1218 sub REALmodsubtitle {
1219 my ( $dbh, $bibnum, $subtitle ) = @_;
1222 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1223 $sth->execute( $subtitle, $bibnum );
1227 =head2 REALmodaddauthor
1229 REALmodaddauthor($dbh,$bibnum,$author);
1233 adds or modify additional authors
1234 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1240 sub REALmodaddauthor {
1241 my ( $dbh, $bibnum, @authors ) = @_;
1243 # my $dbh = C4Connect;
1245 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1247 $sth->execute($bibnum);
1249 foreach my $author (@authors) {
1250 if ( $author ne '' ) {
1253 "Insert into additionalauthors set author = ?, biblionumber = ?"
1256 $sth->execute( $author, $bibnum );
1261 } # sub modaddauthor
1263 =head2 REALmodsubject
1265 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1269 modify/adds subjects
1274 sub REALmodsubject {
1275 my ( $dbh, $bibnum, $force, @subject ) = @_;
1277 # my $dbh = C4Connect;
1278 my $count = @subject;
1280 for ( my $i = 0 ; $i < $count ; $i++ ) {
1281 $subject[$i] =~ s/^ //g;
1282 $subject[$i] =~ s/ $//g;
1285 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1287 $sth->execute( $subject[$i] );
1289 if ( my $data = $sth->fetchrow_hashref ) {
1292 if ( $force eq $subject[$i] || $force == 1 ) {
1294 # subject not in aut, chosen to force anway
1295 # so insert into cataloguentry so its in auth file
1298 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1301 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1306 "$subject[$i]\n does not exist in the subject authority file";
1309 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1311 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1313 while ( my $data = $sth2->fetchrow_hashref ) {
1314 $error .= "<br>$data->{'catalogueentry'}";
1323 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1324 $sth->execute($bibnum);
1328 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1330 foreach $query (@subject) {
1331 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1340 =head2 REALmodbiblioitem
1342 REALmodbiblioitem($dbh, $biblioitem);
1351 sub REALmodbiblioitem {
1352 my ( $dbh, $biblioitem ) = @_;
1355 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1356 itemtype=?, url=?, isbn=?, issn=?,
1357 publishercode=?, publicationyear=?, classification=?, dewey=?,
1358 subclass=?, illus=?, pages=?, volumeddesc=?,
1359 notes=?, size=?, place=?, marc=?,
1361 where biblioitemnumber=?");
1362 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1363 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1364 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1365 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1366 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1367 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1369 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1371 z3950_extended_services('update',set_service_options('update'),$record);
1374 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1377 =head2 REALnewbiblioitem
1379 REALnewbiblioitem($dbh,$biblioitem);
1383 adds a biblioitem ($biblioitem is a hash with the values)
1389 sub REALnewbiblioitem {
1390 my ( $dbh, $biblioitem ) = @_;
1392 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1393 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1395 my $biblioitemnumber;
1398 $data = $sth->fetchrow_arrayref;
1399 $biblioitemnumber = $$data[0] + 1;
1401 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1402 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1403 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1404 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1405 my $field=$record->field($biblioitemnumberfield);
1406 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1407 $biblioitem->{marc} = $record->as_usmarc();
1408 $biblioitem->{marcxml} = $record->as_xml();
1410 $sth = $dbh->prepare( "insert into biblioitems set
1411 biblioitemnumber = ?, biblionumber = ?,
1412 volume = ?, number = ?,
1413 classification = ?, itemtype = ?,
1415 issn = ?, dewey = ?,
1416 subclass = ?, publicationyear = ?,
1417 publishercode = ?, volumedate = ?,
1418 volumeddesc = ?, illus = ?,
1419 pages = ?, notes = ?,
1421 marc = ?, place = ?,
1425 $biblioitemnumber, $biblioitem->{'biblionumber'},
1426 $biblioitem->{'volume'}, $biblioitem->{'number'},
1427 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1428 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1429 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1430 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1431 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1432 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1433 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1434 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1435 $biblioitem->{'marc'}, $biblioitem->{'place'},
1436 $biblioitem->{marcxml},
1438 $dbh->do("unlock tables");
1439 z3950_extended_services('update',set_service_options('update'),$record);
1440 return ($biblioitemnumber);
1443 =head2 REALnewsubtitle
1445 REALnewsubtitle($dbh,$bibnum,$subtitle);
1449 create a new subtitle
1454 sub REALnewsubtitle {
1455 my ( $dbh, $bibnum, $subtitle ) = @_;
1458 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1459 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1465 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1469 create a item. $item is a hash and $barcode the barcode.
1476 my ( $dbh, $item, $barcode ) = @_;
1478 # warn "OLDNEWITEMS";
1480 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1481 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1486 $data = $sth->fetchrow_hashref;
1487 $itemnumber = $data->{'max(itemnumber)'} + 1;
1489 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1490 if ( $item->{'loan'} ) {
1491 $item->{'notforloan'} = $item->{'loan'};
1493 $item->{'biblioitemnumber'} = 1;
1494 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1495 if ( $item->{'dateaccessioned'} ) {
1496 $sth = $dbh->prepare( "Insert into items set
1497 itemnumber = ?, biblionumber = ?,
1498 multivolumepart = ?,
1499 biblioitemnumber = ?, barcode = ?,
1500 booksellerid = ?, dateaccessioned = ?,
1501 homebranch = ?, holdingbranch = ?,
1502 price = ?, replacementprice = ?,
1503 replacementpricedate = NOW(), datelastseen = NOW(),
1504 multivolume = ?, stack = ?,
1505 itemlost = ?, wthdrawn = ?,
1506 paidfor = ?, itemnotes = ?,
1507 itemcallnumber =?, notforloan = ?,
1512 $itemnumber, $item->{'biblionumber'},
1513 $item->{'multivolumepart'},
1514 $item->{'biblioitemnumber'},$item->{barcode},
1515 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1516 $item->{'homebranch'}, $item->{'holdingbranch'},
1517 $item->{'price'}, $item->{'replacementprice'},
1518 $item->{multivolume}, $item->{stack},
1519 $item->{itemlost}, $item->{wthdrawn},
1520 $item->{paidfor}, $item->{'itemnotes'},
1521 $item->{'itemcallnumber'}, $item->{'notforloan'},
1524 if ( defined $sth->errstr ) {
1525 $error .= $sth->errstr;
1529 $sth = $dbh->prepare( "Insert into items set
1530 itemnumber = ?, biblionumber = ?,
1531 multivolumepart = ?,
1532 biblioitemnumber = ?, barcode = ?,
1533 booksellerid = ?, dateaccessioned = NOW(),
1534 homebranch = ?, holdingbranch = ?,
1535 price = ?, replacementprice = ?,
1536 replacementpricedate = NOW(), datelastseen = NOW(),
1537 multivolume = ?, stack = ?,
1538 itemlost = ?, wthdrawn = ?,
1539 paidfor = ?, itemnotes = ?,
1540 itemcallnumber =?, notforloan = ?,
1545 $itemnumber, $item->{'biblionumber'},
1546 $item->{'multivolumepart'},
1547 $item->{'biblioitemnumber'},$item->{barcode},
1548 $item->{'booksellerid'},
1549 $item->{'homebranch'}, $item->{'holdingbranch'},
1550 $item->{'price'}, $item->{'replacementprice'},
1551 $item->{multivolume}, $item->{stack},
1552 $item->{itemlost}, $item->{wthdrawn},
1553 $item->{paidfor}, $item->{'itemnotes'},
1554 $item->{'itemcallnumber'}, $item->{'notforloan'},
1557 if ( defined $sth->errstr ) {
1558 $error .= $sth->errstr;
1561 # item stored, now, deal with the marc part...
1562 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1563 where biblio.biblionumber=biblioitems.biblionumber and
1564 biblio.biblionumber=?");
1565 $sth->execute($item->{biblionumber});
1566 if ( defined $sth->errstr ) {
1567 $error .= $sth->errstr;
1569 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1570 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1571 my $record = MARC::File::USMARC::decode($rawmarc);
1572 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1573 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1574 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1576 #warn $itemnumberfield;
1577 #warn $itemrecord->field($itemnumberfield);
1578 my $itemfield = $itemrecord->field($itemnumberfield);
1579 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1580 $record->insert_grouped_field($itemfield);
1581 # save the record into biblioitem
1582 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1583 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1584 if ( defined $sth->errstr ) {
1585 $error .= $sth->errstr;
1587 z3950_extended_services('update',set_service_options('update'),$record);
1588 $dbh->do('unlock tables');
1589 return ( $itemnumber, $error );
1592 =head2 REALmoditem($dbh,$item);
1603 my ( $dbh, $item ) = @_;
1604 $item->{'bibitemnum'} = 1;
1606 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1607 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1608 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1610 $item->{'barcode'}, $item->{'itemnotes'},
1611 $item->{'itemcallnumber'}, $item->{'notforloan'},
1612 $item->{'location'}, $item->{multivolumepart},
1613 $item->{multivolume}, $item->{stack},
1616 if ( $item->{'lost'} ne '' ) {
1617 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1618 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1619 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1621 $item->{'bibitemnum'}, $item->{'barcode'},
1622 $item->{'itemnotes'}, $item->{'homebranch'},
1623 $item->{'lost'}, $item->{'wthdrawn'},
1624 $item->{'itemcallnumber'}, $item->{'notforloan'},
1625 $item->{'location'}, $item->{multivolumepart},
1626 $item->{multivolume}, $item->{stack},
1629 if ($item->{homebranch}) {
1630 $query.=",homebranch=?";
1631 push @bind, $item->{homebranch};
1633 if ($item->{holdingbranch}) {
1634 $query.=",holdingbranch=?";
1635 push @bind, $item->{holdingbranch};
1638 $query.=" where itemnumber=?";
1639 push @bind,$item->{'itemnum'};
1640 if ( $item->{'replacement'} ne '' ) {
1641 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1643 my $sth = $dbh->prepare($query);
1644 $sth->execute(@bind);
1646 # item stored, now, deal with the marc part...
1647 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1648 where biblio.biblionumber=biblioitems.biblionumber and
1649 biblio.biblionumber=? and
1650 biblioitems.biblioitemnumber=?");
1651 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1652 if ( defined $sth->errstr ) {
1653 $error .= $sth->errstr;
1655 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1656 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1657 my $record = MARC::File::USMARC::decode($rawmarc);
1658 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1659 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1660 # prepare the new item record
1661 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1662 my $itemfield = $itemrecord->field($itemnumberfield);
1663 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1664 # parse all fields fields from the complete record
1665 foreach ($record->field($itemnumberfield)) {
1666 # when the previous field is found, replace by the new one
1667 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1668 $_->replace_with($itemfield);
1671 # $record->insert_grouped_field($itemfield);
1672 # save the record into biblioitem
1673 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1674 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1675 z3950_extended_services('update',set_service_options('update'),$record);
1676 if ( defined $sth->errstr ) {
1677 $error .= $sth->errstr;
1679 $dbh->do('unlock tables');
1683 =head2 REALdelitem($dbh,$itemnum);
1694 my ( $dbh, $itemnum ) = @_;
1696 # my $dbh=C4Connect;
1697 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1698 $sth->execute($itemnum);
1699 my $data = $sth->fetchrow_hashref;
1701 my $query = "Insert into deleteditems set ";
1703 foreach my $temp ( keys %$data ) {
1704 $query .= "$temp = ?,";
1705 push ( @bind, $data->{$temp} );
1710 $sth = $dbh->prepare($query);
1711 $sth->execute(@bind);
1713 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1714 $sth->execute($itemnum);
1720 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1724 deletes a biblioitem
1725 NOTE : not standard sub name. Should be REALdelbiblioitem()
1731 sub REALdelbiblioitem {
1732 my ( $dbh, $biblioitemnumber ) = @_;
1734 # my $dbh = C4Connect;
1735 my $sth = $dbh->prepare( "Select * from biblioitems
1736 where biblioitemnumber = ?"
1740 $sth->execute($biblioitemnumber);
1742 if ( $results = $sth->fetchrow_hashref ) {
1746 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1747 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1748 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1752 $results->{biblioitemnumber}, $results->{biblionumber},
1753 $results->{volume}, $results->{number},
1754 $results->{classification}, $results->{itemtype},
1755 $results->{isbn}, $results->{issn},
1756 $results->{dewey}, $results->{subclass},
1757 $results->{publicationyear}, $results->{publishercode},
1758 $results->{volumedate}, $results->{volumeddesc},
1759 $results->{timestamp}, $results->{illus},
1760 $results->{pages}, $results->{notes},
1761 $results->{size}, $results->{url},
1765 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1766 $sth2->execute($biblioitemnumber);
1771 # Now delete all the items attached to the biblioitem
1772 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1773 $sth->execute($biblioitemnumber);
1775 while ( my $data = $sth->fetchrow_hashref ) {
1776 my $query = "Insert into deleteditems set ";
1778 foreach my $temp ( keys %$data ) {
1779 $query .= "$temp = ?,";
1780 push ( @bind, $data->{$temp} );
1783 my $sth2 = $dbh->prepare($query);
1784 $sth2->execute(@bind);
1787 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1788 $sth->execute($biblioitemnumber);
1792 } # sub deletebiblioitem
1794 =head2 REALdelbiblio($dbh,$biblio);
1805 my ( $dbh, $biblio ) = @_;
1806 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1807 $sth->execute($biblio);
1808 if ( my $data = $sth->fetchrow_hashref ) {
1810 my $query = "Insert into deletedbiblio set ";
1812 foreach my $temp ( keys %$data ) {
1813 $query .= "$temp = ?,";
1814 push ( @bind, $data->{$temp} );
1817 #replacing the last , by ",?)"
1819 $sth = $dbh->prepare($query);
1820 $sth->execute(@bind);
1822 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1823 $sth->execute($biblio);
1831 $number = itemcount($biblio);
1835 returns the number of items attached to a biblio
1843 my $dbh = C4::Context->dbh;
1846 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1847 $sth->execute($biblio);
1848 my $data = $sth->fetchrow_hashref;
1850 return ( $data->{'count(*)'} );
1855 $biblionumber = newbiblio($biblio);
1859 create a biblio. The parameter is a hash
1867 my $dbh = C4::Context->dbh;
1868 my $bibnum = REALnewbiblio( $dbh, $biblio );
1869 # finds new (MARC bibid
1870 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1871 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1872 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1878 $biblionumber = &modbiblio($biblio);
1882 Update a biblio record.
1884 C<$biblio> is a reference-to-hash whose keys are the fields in the
1885 biblio table in the Koha database. All fields must be present, not
1886 just the ones you wish to change.
1888 C<&modbiblio> updates the record defined by
1889 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1891 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1900 my $dbh = C4::Context->dbh;
1901 my $biblionumber=REALmodbiblio($dbh,$biblio);
1902 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1903 # finds new (MARC bibid
1904 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1905 MARCmodbiblio($dbh,$bibid,$record,"",0);
1906 return($biblionumber);
1909 =head2 &modsubtitle($biblionumber, $subtitle);
1913 Sets the subtitle of a book.
1915 C<$biblionumber> is the biblionumber of the book to modify.
1917 C<$subtitle> is the new subtitle.
1924 my ( $bibnum, $subtitle ) = @_;
1925 my $dbh = C4::Context->dbh;
1926 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1929 =head2 &modaddauthor($biblionumber, $author);
1933 Replaces all additional authors for the book with biblio number
1934 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1935 C<&modaddauthor> deletes all additional authors.
1942 my ( $bibnum, @authors ) = @_;
1943 my $dbh = C4::Context->dbh;
1944 &REALmodaddauthor( $dbh, $bibnum, @authors );
1945 } # sub modaddauthor
1949 $error = &modsubject($biblionumber, $force, @subjects);
1953 $force - a subject to force
1954 $error - Error message, or undef if successful.
1961 my ( $bibnum, $force, @subject ) = @_;
1962 my $dbh = C4::Context->dbh;
1963 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1965 # When MARC is off, ensures that the MARC biblio table gets updated with new
1966 # subjects, of course, it deletes the biblio in marc, and then recreates.
1967 # This check is to ensure that no MARC data exists to lose.
1968 # if (C4::Context->preference("MARC") eq '0'){
1969 # warn "in modSUBJECT";
1970 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1971 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1972 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1978 =head2 modbibitem($dbh, $biblioitem);
1982 modify a biblioitem. The parameter is a hash
1989 my ($dbh, $biblioitem) = @_;
1990 #my $dbh = C4::Context->dbh;
1991 &REALmodbiblioitem( $dbh, $biblioitem );
1994 =head2 newbiblioitem
1996 $biblioitemnumber = newbiblioitem($biblioitem)
2000 create a biblioitem, the parameter is a hash
2007 my ($dbh, $biblioitem) = @_;
2008 #my $dbh = C4::Context->dbh;
2009 # add biblio information to the hash
2010 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
2011 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
2012 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
2013 return ($bibitemnum);
2016 =head2 newsubtitle($biblionumber,$subtitle);
2020 insert a subtitle for $biblionumber biblio
2028 my ( $bibnum, $subtitle ) = @_;
2029 my $dbh = C4::Context->dbh;
2030 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
2035 $errors = newitems($dbh, $item, @barcodes);
2039 insert items ($item is a hash)
2047 my ( $dbh, $item, @barcodes ) = @_;
2048 #my $dbh = C4::Context->dbh;
2052 foreach my $barcode (@barcodes) {
2053 # add items, one by one for each barcode.
2055 $oneitem->{barcode}= $barcode;
2056 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2057 $oneitem->{marc} = $MARCitem->as_usmarc;
2058 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2059 # $errors .= $error;
2060 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2065 =head2 moditem($dbh,$item);
2069 modify an item ($item is a hash with all item informations)
2077 my ($dbh, $item) = @_;
2078 #my $dbh = C4::Context->dbh;
2079 &REALmoditem( $dbh, $item );
2081 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2083 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2084 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2089 $error = checkitems($count,@barcodes);
2093 check for each @barcode entry that the barcode is not a duplicate
2100 my ( $count, @barcodes ) = @_;
2101 my $dbh = C4::Context->dbh;
2103 my $sth = $dbh->prepare("Select * from items where barcode=?");
2104 for ( my $i = 0 ; $i < $count ; $i++ ) {
2105 $barcodes[$i] = uc $barcodes[$i];
2106 $sth->execute( $barcodes[$i] );
2107 if ( my $data = $sth->fetchrow_hashref ) {
2108 $error .= " Duplicate Barcode: $barcodes[$i]";
2115 =head2 delitem($itemnum);
2119 delete item $itemnum being the item number to delete
2127 my $dbh = C4::Context->dbh;
2128 &REALdelitem( $dbh, $itemnum );
2131 =head2 deletebiblioitem($biblioitemnumber);
2135 delete the biblioitem $biblioitemnumber
2141 sub deletebiblioitem {
2142 my ($biblioitemnumber) = @_;
2143 my $dbh = C4::Context->dbh;
2144 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2145 } # sub deletebiblioitem
2147 =head2 delbiblio($biblionumber)
2151 delete biblio $biblionumber
2159 my $dbh = C4::Context->dbh;
2160 &REALdelbiblio( $dbh, $biblio );
2161 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2162 &MARCdelbiblio( $dbh, $bibid, 0 );
2167 ($count,@results) = getbiblio($biblionumber);
2171 return an array with hash of biblios.
2173 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2180 my ($biblionumber) = @_;
2181 my $dbh = C4::Context->dbh;
2182 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2184 # || die "Cannot prepare $query\n" . $dbh->errstr;
2188 $sth->execute($biblionumber);
2190 # || die "Cannot execute $query\n" . $sth->errstr;
2191 while ( my $data = $sth->fetchrow_hashref ) {
2192 $results[$count] = $data;
2197 return ( $count, @results );
2202 $data = &bibdata($biblionumber, $type);
2204 Returns information about the book with the given biblionumber.
2206 C<$type> is ignored.
2208 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2209 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2212 In addition, C<$data-E<gt>{subject}> is the list of the book's
2213 subjects, separated by C<" , "> (space, comma, space).
2215 If there are multiple biblioitems with the given biblionumber, only
2216 the first one is considered.
2221 my ($bibnum, $type) = @_;
2222 my $dbh = C4::Context->dbh;
2223 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2225 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2226 left join bibliosubtitle on
2227 biblio.biblionumber = bibliosubtitle.biblionumber
2228 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2229 where biblio.biblionumber = ?
2231 $sth->execute($bibnum);
2233 $data = $sth->fetchrow_hashref;
2235 # handle management of repeated subtitle
2236 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2237 $sth->execute($bibnum);
2239 while (my $dat = $sth->fetchrow_hashref){
2241 $line{subtitle} = $dat->{subtitle};
2242 push @subtitles, \%line;
2244 $data->{subtitles} = \@subtitles;
2246 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2247 $sth->execute($bibnum);
2249 while (my $dat = $sth->fetchrow_hashref){
2251 $line{subject} = $dat->{'subject'};
2252 push @subjects, \%line;
2254 $data->{subjects} = \@subjects;
2256 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2257 $sth->execute($bibnum);
2258 while (my $dat = $sth->fetchrow_hashref){
2259 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2261 chop $data->{'additionalauthors'};
2262 chop $data->{'additionalauthors'};
2263 chop $data->{'additionalauthors'};
2268 =head2 getbiblioitem
2270 ($count,@results) = getbiblioitem($biblioitemnumber);
2274 return an array with hash of biblioitemss.
2276 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2283 my ($biblioitemnum) = @_;
2284 my $dbh = C4::Context->dbh;
2285 my $sth = $dbh->prepare( "Select * from biblioitems where
2286 biblioitemnumber = ?"
2291 $sth->execute($biblioitemnum);
2293 while ( my $data = $sth->fetchrow_hashref ) {
2294 $results[$count] = $data;
2299 return ( $count, @results );
2300 } # sub getbiblioitem
2302 =head2 getbiblioitembybiblionumber
2304 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2308 return an array with hash of biblioitems for the given biblionumber.
2314 sub getbiblioitembybiblionumber {
2315 my ($biblionumber) = @_;
2316 my $dbh = C4::Context->dbh;
2317 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2321 $sth->execute($biblionumber);
2323 while ( my $data = $sth->fetchrow_hashref ) {
2324 $results[$count] = $data;
2329 return ( $count, @results );
2332 =head2 getitemsbybiblioitem
2334 ($count,@results) = getitemsbybiblioitem($biblionumber);
2338 returns an array with hash of items
2344 sub getitemsbybiblioitem {
2345 my ($biblioitemnum) = @_;
2346 my $dbh = C4::Context->dbh;
2347 my $sth = $dbh->prepare( "Select * from items, biblio where
2348 biblio.biblionumber = items.biblionumber and biblioitemnumber
2352 # || die "Cannot prepare $query\n" . $dbh->errstr;
2356 $sth->execute($biblioitemnum);
2358 # || die "Cannot execute $query\n" . $sth->errstr;
2359 while ( my $data = $sth->fetchrow_hashref ) {
2360 $results[$count] = $data;
2365 return ( $count, @results );
2366 } # sub getitemsbybiblioitem
2370 @results = &ItemInfo($env, $biblionumber, $type);
2372 Returns information about books with the given biblionumber.
2374 C<$type> may be either C<intra> or anything else. If it is not set to
2375 C<intra>, then the search will exclude lost, very overdue, and
2380 C<&ItemInfo> returns a list of references-to-hash. Each element
2381 contains a number of keys. Most of them are table items from the
2382 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2383 Koha database. Other keys include:
2387 =item C<$data-E<gt>{branchname}>
2389 The name (not the code) of the branch to which the book belongs.
2391 =item C<$data-E<gt>{datelastseen}>
2393 This is simply C<items.datelastseen>, except that while the date is
2394 stored in YYYY-MM-DD format in the database, here it is converted to
2395 DD/MM/YYYY format. A NULL date is returned as C<//>.
2397 =item C<$data-E<gt>{datedue}>
2399 =item C<$data-E<gt>{class}>
2401 This is the concatenation of C<biblioitems.classification>, the book's
2402 Dewey code, and C<biblioitems.subclass>.
2404 =item C<$data-E<gt>{ocount}>
2406 I think this is the number of copies of the book available.
2408 =item C<$data-E<gt>{order}>
2410 If this is set, it is set to C<One Order>.
2417 my ($env,$biblionumber,$type) = @_;
2418 my $dbh = C4::Context->dbh;
2419 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2420 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2421 WHERE items.biblionumber = ?
2422 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2423 AND biblio.biblionumber = items.biblionumber";
2424 $query .= " order by items.dateaccessioned desc";
2425 my $sth=$dbh->prepare($query);
2426 $sth->execute($biblionumber);
2429 while (my $data=$sth->fetchrow_hashref){
2431 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2432 $isth->execute($data->{'itemnumber'});
2433 if (my $idata=$isth->fetchrow_hashref){
2434 $data->{borrowernumber} = $idata->{borrowernumber};
2435 $data->{cardnumber} = $idata->{cardnumber};
2436 $datedue = format_date($idata->{'date_due'});
2438 if ($datedue eq ''){
2439 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2445 #get branch information.....
2446 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2447 $bsth->execute($data->{'holdingbranch'});
2448 if (my $bdata=$bsth->fetchrow_hashref){
2449 $data->{'branchname'} = $bdata->{'branchname'};
2451 my $date=format_date($data->{'datelastseen'});
2452 $data->{'datelastseen'}=$date;
2453 $data->{'datedue'}=$datedue;
2454 # get notforloan complete status if applicable
2455 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2456 $sthnflstatus->execute;
2457 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2458 if ($authorised_valuecode) {
2459 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2460 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2461 my ($lib) = $sthnflstatus->fetchrow;
2462 $data->{notforloan} = $lib;
2473 ($count, @results) = &bibitems($biblionumber);
2475 Given the biblionumber for a book, C<&bibitems> looks up that book's
2476 biblioitems (different publications of the same book, the audio book
2477 and film versions, etc.).
2479 C<$count> is the number of elements in C<@results>.
2481 C<@results> is an array of references-to-hash; the keys are the fields
2482 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2483 addition, C<itemlost> indicates the availability of the item: if it is
2484 "2", then all copies of the item are long overdue; if it is "1", then
2485 all copies are lost; otherwise, there is at least one copy available.
2491 my $dbh = C4::Context->dbh;
2492 my $sth = $dbh->prepare("SELECT biblioitems.*,
2494 MIN(items.itemlost) as itemlost,
2495 MIN(items.dateaccessioned) as dateaccessioned
2496 FROM biblioitems, itemtypes, items
2497 WHERE biblioitems.biblionumber = ?
2498 AND biblioitems.itemtype = itemtypes.itemtype
2499 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2500 GROUP BY items.biblioitemnumber");
2503 $sth->execute($bibnum);
2504 while (my $data = $sth->fetchrow_hashref) {
2505 $results[$count] = $data;
2509 return($count, @results);
2515 $itemdata = &bibitemdata($biblioitemnumber);
2517 Looks up the biblioitem with the given biblioitemnumber. Returns a
2518 reference-to-hash. The keys are the fields from the C<biblio>,
2519 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2520 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2526 my $dbh = C4::Context->dbh;
2527 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");
2530 $sth->execute($bibitem);
2532 $data = $sth->fetchrow_hashref;
2539 =head2 getbibliofromitemnumber
2541 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2543 Looks up the item with the given itemnumber.
2545 C<$env> and C<$dbh> are ignored.
2547 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2548 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2553 sub getbibliofromitemnumber {
2554 my ($env,$dbh,$itemnumber) = @_;
2555 $dbh = C4::Context->dbh;
2556 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2557 where items.itemnumber = ?
2558 and biblio.biblionumber = items.biblionumber
2559 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2561 $sth->execute($itemnumber);
2562 my $data=$sth->fetchrow_hashref;
2569 @barcodes = &barcodes($biblioitemnumber);
2571 Given a biblioitemnumber, looks up the corresponding items.
2573 Returns an array of references-to-hash; the keys are C<barcode> and
2576 The returned items include very overdue items, but not lost ones.
2581 #called from request.pl
2582 my ($biblioitemnumber)=@_;
2583 my $dbh = C4::Context->dbh;
2584 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2585 WHERE biblioitemnumber = ?
2586 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2587 $sth->execute($biblioitemnumber);
2590 while (my $data=$sth->fetchrow_hashref){
2591 $barcodes[$i]=$data;
2601 $item = &itemdata($barcode);
2603 Looks up the item with the given barcode, and returns a
2604 reference-to-hash containing information about that item. The keys of
2605 the hash are the fields from the C<items> and C<biblioitems> tables in
2610 sub get_item_from_barcode {
2612 my $dbh = C4::Context->dbh;
2613 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2614 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2615 $sth->execute($barcode);
2616 my $data=$sth->fetchrow_hashref;
2624 @issues = &itemissues($biblioitemnumber, $biblio);
2626 Looks up information about who has borrowed the bookZ<>(s) with the
2627 given biblioitemnumber.
2629 C<$biblio> is ignored.
2631 C<&itemissues> returns an array of references-to-hash. The keys
2632 include the fields from the C<items> table in the Koha database.
2633 Additional keys include:
2639 If the item is currently on loan, this gives the due date.
2641 If the item is not on loan, then this is either "Available" or
2642 "Cancelled", if the item has been withdrawn.
2646 If the item is currently on loan, this gives the card number of the
2647 patron who currently has the item.
2649 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2651 These give the timestamp for the last three times the item was
2654 =item C<card0>, C<card1>, C<card2>
2656 The card number of the last three patrons who borrowed this item.
2658 =item C<borrower0>, C<borrower1>, C<borrower2>
2660 The borrower number of the last three patrons who borrowed this item.
2667 my ($bibitem, $biblio)=@_;
2668 my $dbh = C4::Context->dbh;
2669 # FIXME - If this function die()s, the script will abort, and the
2670 # user won't get anything; depending on how far the script has
2671 # gotten, the user might get a blank page. It would be much better
2672 # to at least print an error message. The easiest way to do this
2673 # is to set $SIG{__DIE__}.
2674 my $sth = $dbh->prepare("Select * from items where
2675 items.biblioitemnumber = ?")
2676 || die $dbh->errstr;
2680 $sth->execute($bibitem)
2681 || die $sth->errstr;
2683 while (my $data = $sth->fetchrow_hashref) {
2684 # Find out who currently has this item.
2685 # FIXME - Wouldn't it be better to do this as a left join of
2686 # some sort? Currently, this code assumes that if
2687 # fetchrow_hashref() fails, then the book is on the shelf.
2688 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2689 # database server crash), not just because no items match the
2691 my $sth2 = $dbh->prepare("select * from issues,borrowers
2692 where itemnumber = ?
2693 and returndate is NULL
2694 and issues.borrowernumber = borrowers.borrowernumber");
2696 $sth2->execute($data->{'itemnumber'});
2697 if (my $data2 = $sth2->fetchrow_hashref) {
2698 $data->{'date_due'} = $data2->{'date_due'};
2699 $data->{'card'} = $data2->{'cardnumber'};
2700 $data->{'borrower'} = $data2->{'borrowernumber'};
2702 if ($data->{'wthdrawn'} eq '1') {
2703 $data->{'date_due'} = 'Cancelled';
2705 $data->{'date_due'} = 'Available';
2711 # Find the last 3 people who borrowed this item.
2712 $sth2 = $dbh->prepare("select * from issues, borrowers
2713 where itemnumber = ?
2714 and issues.borrowernumber = borrowers.borrowernumber
2715 and returndate is not NULL
2716 order by returndate desc,timestamp desc") || die $dbh->errstr;
2717 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2718 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2719 if (my $data2 = $sth2->fetchrow_hashref) {
2720 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2721 $data->{"card$i2"} = $data2->{'cardnumber'};
2722 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2727 $results[$i] = $data;
2737 ($count, $subjects) = &getsubject($biblionumber);
2739 Looks up the subjects of the book with the given biblionumber. Returns
2740 a two-element list. C<$subjects> is a reference-to-array, where each
2741 element is a subject of the book, and C<$count> is the number of
2742 elements in C<$subjects>.
2748 my $dbh = C4::Context->dbh;
2749 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2750 $sth->execute($bibnum);
2753 while (my $data=$sth->fetchrow_hashref){
2758 return($i,\@results);
2763 ($count, $authors) = &getaddauthor($biblionumber);
2765 Looks up the additional authors for the book with the given
2768 Returns a two-element list. C<$authors> is a reference-to-array, where
2769 each element is an additional author, and C<$count> is the number of
2770 elements in C<$authors>.
2776 my $dbh = C4::Context->dbh;
2777 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2778 $sth->execute($bibnum);
2781 while (my $data=$sth->fetchrow_hashref){
2786 return($i,\@results);
2792 ($count, $subtitles) = &getsubtitle($biblionumber);
2794 Looks up the subtitles for the book with the given biblionumber.
2796 Returns a two-element list. C<$subtitles> is a reference-to-array,
2797 where each element is a subtitle, and C<$count> is the number of
2798 elements in C<$subtitles>.
2804 my $dbh = C4::Context->dbh;
2805 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2806 $sth->execute($bibnum);
2809 while (my $data=$sth->fetchrow_hashref){
2814 return($i,\@results);
2820 ($count, @websites) = &getwebsites($biblionumber);
2822 Looks up the web sites pertaining to the book with the given
2825 C<$count> is the number of elements in C<@websites>.
2827 C<@websites> is an array of references-to-hash; the keys are the
2828 fields from the C<websites> table in the Koha database.
2831 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2832 #(with add / modify / delete subs)
2835 my ($biblionumber) = @_;
2836 my $dbh = C4::Context->dbh;
2837 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2841 $sth->execute($biblionumber);
2842 while (my $data = $sth->fetchrow_hashref) {
2843 # FIXME - The URL scheme shouldn't be stripped off, at least
2844 # not here, since it's part of the URL, and will be useful in
2845 # constructing a link to the site. If you don't want the user
2846 # to see the "http://" part, strip that off when building the
2848 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2850 $results[$count] = $data;
2855 return($count, @results);
2858 =head2 getwebbiblioitems
2860 ($count, @results) = &getwebbiblioitems($biblionumber);
2862 Given a book's biblionumber, looks up the web versions of the book
2863 (biblioitems with itemtype C<WEB>).
2865 C<$count> is the number of items in C<@results>. C<@results> is an
2866 array of references-to-hash; the keys are the items from the
2867 C<biblioitems> table of the Koha database.
2871 sub getwebbiblioitems {
2872 my ($biblionumber) = @_;
2873 my $dbh = C4::Context->dbh;
2874 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2875 and itemtype = 'WEB'");
2879 $sth->execute($biblionumber);
2880 while (my $data = $sth->fetchrow_hashref) {
2881 $data->{'url'} =~ s/^http:\/\///;
2882 $results[$count] = $data;
2887 return($count, @results);
2888 } # sub getwebbiblioitems
2891 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2892 my $NSE = '\x89'; # NSE : Non Sorting Block end
2893 # handles non sorting blocks
2897 s/[ ]{0,1}$NSE/) /gm;
2904 my $dbh = C4::Context->dbh;
2905 my $result = MARCmarc2koha($dbh,$record,'');
2907 my ($biblionumber,$bibid,$title);
2908 # search duplicate on ISBN, easy and fast...
2909 if ($result->{isbn}) {
2910 $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=?");
2911 $sth->execute($result->{'isbn'});
2912 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2913 return $biblionumber,$bibid,$title if ($biblionumber);
2915 # a more complex search : build a request for SearchMarc::catalogsearch()
2916 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2917 # search on biblio.title
2918 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2919 if ($record->field($tag)) {
2920 if ($record->field($tag)->subfields($subfield)) {
2921 push @tags, "'".$tag.$subfield."'";
2922 push @and_or, "and";
2923 push @excluding, "";
2924 push @operator, "contains";
2925 push @value, $record->field($tag)->subfield($subfield);
2926 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2929 # ... and on biblio.author
2930 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2931 if ($record->field($tag)) {
2932 if ($record->field($tag)->subfields($subfield)) {
2933 push @tags, "'".$tag.$subfield."'";
2934 push @and_or, "and";
2935 push @excluding, "";
2936 push @operator, "contains";
2937 push @value, $record->field($tag)->subfield($subfield);
2938 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2941 # ... and on publicationyear.
2942 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2943 if ($record->field($tag)) {
2944 if ($record->field($tag)->subfields($subfield)) {
2945 push @tags, "'".$tag.$subfield."'";
2946 push @and_or, "and";
2947 push @excluding, "";
2948 push @operator, "=";
2949 push @value, $record->field($tag)->subfield($subfield);
2950 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2954 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2955 if ($record->field($tag)) {
2956 if ($record->field($tag)->subfields($subfield)) {
2957 push @tags, "'".$tag.$subfield."'";
2958 push @and_or, "and";
2959 push @excluding, "";
2960 push @operator, "=";
2961 push @value, $record->field($tag)->subfield($subfield);
2962 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2965 # ... and on publisher.
2966 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2967 if ($record->field($tag)) {
2968 if ($record->field($tag)->subfields($subfield)) {
2969 push @tags, "'".$tag.$subfield."'";
2970 push @and_or, "and";
2971 push @excluding, "";
2972 push @operator, "=";
2973 push @value, $record->field($tag)->subfield($subfield);
2974 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2977 # ... and on volume.
2978 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2979 if ($record->field($tag)) {
2980 if ($record->field($tag)->subfields($subfield)) {
2981 push @tags, "'".$tag.$subfield."'";
2982 push @and_or, "and";
2983 push @excluding, "";
2984 push @operator, "=";
2985 push @value, $record->field($tag)->subfield($subfield);
2986 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2990 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2991 # there is at least 1 result => return the 1st one
2993 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2994 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2996 # no result, returns nothing
3003 if(substr($isbn, 0, 1) <=7) {
3004 $seg1 = substr($isbn, 0, 1);
3005 } elsif(substr($isbn, 0, 2) <= 94) {
3006 $seg1 = substr($isbn, 0, 2);
3007 } elsif(substr($isbn, 0, 3) <= 995) {
3008 $seg1 = substr($isbn, 0, 3);
3009 } elsif(substr($isbn, 0, 4) <= 9989) {
3010 $seg1 = substr($isbn, 0, 4);
3012 $seg1 = substr($isbn, 0, 5);
3014 my $x = substr($isbn, length($seg1));
3016 if(substr($x, 0, 2) <= 19) {
3017 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
3018 $seg2 = substr($x, 0, 2);
3019 } elsif(substr($x, 0, 3) <= 699) {
3020 $seg2 = substr($x, 0, 3);
3021 } elsif(substr($x, 0, 4) <= 8399) {
3022 $seg2 = substr($x, 0, 4);
3023 } elsif(substr($x, 0, 5) <= 89999) {
3024 $seg2 = substr($x, 0, 5);
3025 } elsif(substr($x, 0, 6) <= 9499999) {
3026 $seg2 = substr($x, 0, 6);
3028 $seg2 = substr($x, 0, 7);
3030 my $seg3=substr($x,length($seg2));
3031 $seg3=substr($seg3,0,length($seg3)-1) ;
3032 my $seg4 = substr($x, -1, 1);
3033 return "$seg1-$seg2-$seg3-$seg4";
3037 END { } # module clean-up code here (global destructor)
3043 Koha Developement team <info@koha.org>
3045 Paul POULAIN paul.poulain@free.fr
3051 # Revision 1.160 2006/03/07 22:00:18 kados
3052 # adding support for 'delete' function
3054 # Revision 1.159 2006/03/07 21:54:47 rangi
3055 # Starting work on deletes
3057 # Revision 1.158 2006/03/06 02:45:41 kados
3058 # Adding fixes to MARC editor to HEAD
3060 # Revision 1.157 2006/03/01 03:07:54 kados
3061 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3063 # Revision 1.155 2006/02/27 01:08:31 kados
3064 # Removing 'our Zconn' from top...
3066 # Revision 1.154 2006/02/26 00:08:20 kados
3067 # moving all $Zconn s to z3950_extended_services (currently, nothing
3070 # Revision 1.153 2006/02/25 22:39:10 kados
3071 # Another purely documentation commit. Just changing formatting to ease
3074 # Revision 1.152 2006/02/25 21:17:20 kados
3075 # Purely documentation change: converted all =head2 entries to use function
3076 # name as title rather than usage as title
3078 # Revision 1.151 2006/02/25 21:02:20 kados
3080 # Further cleanup, convering new routines to 4-chars
3082 # Revision 1.150 2006/02/25 20:49:15 kados
3083 # Better documentation, added warning if serviceType is 'drop' since it's
3084 # not supported in Zebra.
3086 # Revision 1.149 2006/02/25 20:30:32 kados
3087 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3088 # longer necessary. If we need to convert from MARC-8 for display, we should:
3091 # 2. do it with MARC::Charset
3093 # If you still need it, let me know and I'll put it back in.
3095 # Revision 1.148 2006/02/25 19:23:01 kados
3096 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3097 # replaced by z3950_extended_services).
3099 # Revision 1.147 2006/02/25 19:09:59 kados
3100 # readding some lost subs
3102 # Revision 1.145 2006/02/22 01:02:39 kados
3103 # Replacing all calls to zebra_update with calls to
3104 # z3950_extended_services. More work coming, but it's
3107 # Revision 1.144 2006/02/20 14:22:38 kados
3110 # Revision 1.143 2006/02/20 13:26:11 kados
3111 # A new subroutine to handle Z39.50 extended services. You pass it a
3112 # connection object, service type, service options, and a record, and
3113 # it performs the service and handles any exception found.
3115 # Revision 1.142 2006/02/16 20:49:56 kados
3116 # destroy a connection after we're done -- we really should just have one
3117 # connection object and not destroy it until the whole transaction is
3118 # finished -- but this will do for now
3120 # Revision 1.141 2006/02/16 19:47:22 rangi
3121 # Trying to error trap a little more.
3123 # Revision 1.140 2006/02/14 21:36:03 kados
3124 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3125 # also adding diagnostic error if not able to connect to Zebra
3127 # Revision 1.139 2006/02/14 19:53:25 rangi
3128 # Just a little missing my
3130 # Seems to be working great Paul, and I like what you did with zebradb
3132 # Revision 1.138 2006/02/14 11:25:22 tipaul
3133 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3135 # Revision 1.137 2006/02/13 16:34:26 tipaul
3136 # fixing some warnings (perl -w should be quiet)
3138 # Revision 1.136 2006/01/10 17:01:29 tipaul
3139 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3141 # Revision 1.135 2006/01/06 16:39:37 tipaul
3142 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3143 # Seems not to break too many things, but i'm probably wrong here.
3144 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3146 # - removing useless directories (koha-html and koha-plucene)
3148 # Revision 1.134 2006/01/04 15:54:55 tipaul
3149 # utf8 is a : go for beta test in HEAD.
3150 # some explanations :
3151 # - 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.
3152 # - *-top.inc will show the pages in utf8
3153 # - 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.
3154 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3156 # Revision 1.133 2005/12/12 14:25:51 thd
3159 # Reverse array filled with elements from repeated subfields
3160 # to avoid last to first concatenation of elements in Koha DB.-
3162 # Revision 1.132 2005-10-26 09:12:33 tipaul
3163 # big commit, still breaking things...
3165 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3166 # * code cleaning (cleaning warnings from perl -w) continued
3168 # Revision 1.131 2005/09/22 10:01:45 tipaul
3169 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3171 # Revision 1.130 2005/09/02 14:34:14 tipaul
3172 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3173 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3174 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3176 # Revision 1.129 2005/08/12 13:50:31 tipaul
3177 # removing useless sub declarations
3179 # Revision 1.128 2005/08/11 16:12:47 tipaul
3180 # Playing with the zebra...
3182 # * go to koha cvs home directory
3183 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3184 # * put your zebra.cfg files here & create your database.
3185 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3186 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3189 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3190 # * deletion still not work
3191 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3193 # recordId: (bib1,Local-number)
3197 # elm 090 Local-number -
3198 # elm 090/? Local-number -
3199 # elm 090/?/9 Local-number !:w
3201 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3203 # Revision 1.127 2005/08/11 14:37:32 tipaul
3205 # * removing useless subs
3206 # * removing some subs that are also elsewhere
3207 # * 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)
3209 # Revision 1.126 2005/08/11 09:13:28 tipaul
3210 # just removing useless subs (a lot !!!) for code cleaning
3212 # Revision 1.125 2005/08/11 09:00:07 tipaul
3213 # Ok guys, this time, it seems that item add and modif begin working as expected...
3214 # Still a lot of bugs to fix, of course
3216 # Revision 1.124 2005/08/10 10:21:15 tipaul
3217 # continuing the road to zebra :
3218 # - the biblio add begins to work.
3219 # - the biblio modif begins to work.
3221 # (still without doing anything on zebra)
3222 # (no new change in updatedatabase)
3224 # Revision 1.123 2005/08/09 14:10:28 tipaul
3225 # 1st commit to go to zebra.
3226 # don't update your cvs if you want to have a working head...
3228 # this commit contains :
3229 # * 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...
3230 # * 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.
3231 # * other files : get rid of bibid and use biblionumber instead.
3234 # * does not do anything on zebra yet.
3235 # * if you rename marc_subfield_table, you can't search anymore.
3236 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3237 # * 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 ;-) )
3239 # 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
3240 # 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.
3242 # tipaul cutted previous commit notes