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++){
651 @$values[$i] =~ s/&/&/g;
652 @$values[$i] =~ s/</</g;
653 @$values[$i] =~ s/>/>/g;
654 @$values[$i] =~ s/"/"/g;
655 @$values[$i] =~ s/'/'/g;
657 if ((@$tags[$i] ne $prevtag)){
658 $j++ unless (@$tags[$i] eq "");
659 #warn "IND:".substr(@$indicator[$j],0,1).substr(@$indicator[$j],1,1)." ".@$tags[$i];
661 $xml.="</datafield>\n";
662 if ((@$tags[$i] > 10) && (@$values[$i] ne "")){
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] ne "") {
674 if (@$tags[$i] eq "000") {
675 $xml.="<leader>@$values[$i]</leader>\n";
677 # rest of the fixed fields
678 } elsif (@$tags[$i] < 10) {
679 $xml.="<controlfield tag=\"@$tags[$i]\">@$values[$i]</controlfield>\n";
682 my $ind1 = substr(@$indicator[$j],0,1);
683 my $ind2 = substr(@$indicator[$j],1,1);
684 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
685 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
690 } else { # @$tags[$i] eq $prevtag
691 if (@$values[$i] eq "") {
695 my $ind1 = substr(@$indicator[$j],0,1);
696 my $ind2 = substr(@$indicator[$j],1,1);
697 $xml.="<datafield tag=\"@$tags[$i]\" ind1=\"$ind1\" ind2=\"$ind2\">\n";
700 $xml.="<subfield code=\"@$subfields[$i]\">@$values[$i]</subfield>\n";
703 $prevtag = @$tags[$i];
705 $xml.= MARC::File::XML::footer();
712 $hash = &MARCmarc2koha($dbh,$MARCRecord);
716 builds a hash with old-db datas from a MARC::Record
723 my ($dbh,$record,$frameworkcode) = @_;
724 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
726 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
729 while (($field)=$sth2->fetchrow) {
730 # warn "biblio.".$field;
731 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
733 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
735 while (($field)=$sth2->fetchrow) {
736 if ($field eq 'notes') { $field = 'bnotes'; }
737 # warn "biblioitems".$field;
738 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
740 $sth2=$dbh->prepare("SHOW COLUMNS from items");
742 while (($field)=$sth2->fetchrow) {
743 # warn "items".$field;
744 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
746 # additional authors : specific
747 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
748 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
749 # modify copyrightdate to keep only the 1st year found
750 my $temp = $result->{'copyrightdate'};
752 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
754 $result->{'copyrightdate'} = $1;
755 } else { # if no cYYYY, get the 1st date.
756 $temp =~ m/(\d\d\d\d)/;
757 $result->{'copyrightdate'} = $1;
760 # modify publicationyear to keep only the 1st year found
761 $temp = $result->{'publicationyear'};
762 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
764 $result->{'publicationyear'} = $1;
765 } else { # if no cYYYY, get the 1st date.
766 $temp =~ m/(\d\d\d\d)/;
767 $result->{'publicationyear'} = $1;
772 sub MARCmarc2kohaOneField {
774 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
775 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
776 # warn "kohatable / $kohafield / $result / ";
780 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
781 foreach my $field ( $record->field($tagfield) ) {
782 if ($field->tag()<10) {
783 if ($result->{$kohafield}) {
784 # Reverse array filled with elements from repeated subfields
785 # from first to last to avoid last to first concatenation of
786 # elements in Koha DB. -- thd.
787 $result->{$kohafield} .= " | ".reverse($field->data());
789 $result->{$kohafield} = $field->data();
792 if ( $field->subfields ) {
793 my @subfields = $field->subfields();
794 foreach my $subfieldcount ( 0 .. $#subfields ) {
795 if ($subfields[$subfieldcount][0] eq $subfield) {
796 if ( $result->{$kohafield} ) {
797 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
800 $result->{$kohafield} = $subfields[$subfieldcount][1];
807 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
813 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
817 creates a biblio from a MARC::Record.
824 my ( $dbh,$record,$frameworkcode ) = @_;
826 my $biblioitemnumber;
827 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
828 $olddata->{frameworkcode} = $frameworkcode;
829 $biblionumber = REALnewbiblio( $dbh, $olddata );
830 $olddata->{biblionumber} = $biblionumber;
831 # add biblionumber into the MARC record (it's the ID for zebra)
832 my ( $tagfield, $tagsubfield ) =
833 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
837 $newfield = MARC::Field->new(
838 $tagfield, $biblionumber,
841 $newfield = MARC::Field->new(
842 $tagfield, '', '', "$tagsubfield" => $biblionumber,
845 # drop old field (just in case it already exist and create new one...
846 my $old_field = $record->field($tagfield);
847 $record->delete_field($old_field);
848 $record->add_fields($newfield);
850 #create the marc entry, that stores the rax marc record in Koha 3.0
851 $olddata->{marc} = $record->as_usmarc();
852 $olddata->{marcxml} = $record->as_xml();
853 # and create biblioitem, that's all folks !
854 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
856 # search subtiles, addiauthors and subjects
857 ( $tagfield, $tagsubfield ) =
858 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
859 my @addiauthfields = $record->field($tagfield);
860 foreach my $addiauthfield (@addiauthfields) {
861 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
862 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
863 REALmodaddauthor( $dbh, $biblionumber,
864 $addiauthsubfields[$subfieldcount] );
867 ( $tagfield, $tagsubfield ) =
868 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
869 my @subtitlefields = $record->field($tagfield);
870 foreach my $subtitlefield (@subtitlefields) {
871 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
872 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
873 REALnewsubtitle( $dbh, $biblionumber,
874 $subtitlesubfields[$subfieldcount] );
877 ( $tagfield, $tagsubfield ) =
878 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
879 my @subj = $record->field($tagfield);
881 foreach my $subject (@subj) {
882 my @subjsubfield = $subject->subfield($tagsubfield);
883 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
884 push @subjects, $subjsubfield[$subfieldcount];
887 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
888 return ( $biblionumber, $biblioitemnumber );
891 =head2 NEWmodbilbioframework
893 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
897 modify the framework of a biblio
903 sub NEWmodbiblioframework {
904 my ($dbh,$biblionumber,$frameworkcode) =@_;
905 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
906 $sth->execute($frameworkcode,$biblionumber);
912 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
916 modify a biblio (MARC=ON)
923 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
924 $frameworkcode="" unless $frameworkcode;
925 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
926 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
928 $oldbiblio->{frameworkcode} = $frameworkcode;
929 #create the marc entry, that stores the rax marc record in Koha 3.0
930 $oldbiblio->{biblionumber} = $biblionumber unless $oldbiblio->{biblionumber};
931 $oldbiblio->{marc} = $record->as_usmarc();
932 $oldbiblio->{marcxml} = $record->as_xml();
933 warn "dans NEWmodbiblio $biblionumber = ".$oldbiblio->{biblionumber}." = ".$oldbiblio->{marcxml};
934 REALmodbiblio($dbh,$oldbiblio);
935 REALmodbiblioitem($dbh,$oldbiblio);
936 # now, modify addi authors, subject, addititles.
937 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
938 my @addiauthfields = $record->field($tagfield);
939 foreach my $addiauthfield (@addiauthfields) {
940 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
941 $dbh->do("delete from additionalauthors where biblionumber=$biblionumber");
942 foreach my $subfieldcount (0..$#addiauthsubfields) {
943 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
946 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
947 my @subtitlefields = $record->field($tagfield);
948 foreach my $subtitlefield (@subtitlefields) {
949 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
950 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
952 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
953 foreach my $subfieldcount (0..$#subtitlesubfields) {
954 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
955 REALnewsubtitle($dbh,$biblionumber,$subtit);
959 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
960 my @subj = $record->field($tagfield);
962 foreach my $subject (@subj) {
963 my @subjsubfield = $subject->subfield($tagsubfield);
964 foreach my $subfieldcount (0..$#subjsubfield) {
965 push @subjects,$subjsubfield[$subfieldcount];
968 REALmodsubject($dbh,$biblionumber,1,@subjects);
972 =head2 NEWmodbilbioframework
974 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
985 my ( $dbh, $bibid ) = @_;
986 # my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
987 &REALdelbiblio( $dbh, $bibid );
990 "select biblioitemnumber from biblioitems where biblionumber=?");
991 $sth->execute($bibid);
992 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
993 REALdelbiblioitem( $dbh, $biblioitemnumber );
995 # &MARCdelbiblio( $dbh, $bibid, 0 );
997 warn "heres the bibid $bibid";
998 # my $record = C4::Search::get_record($bibid);
999 my $record = C4::Search::get_xml_record($bibid);
1000 # z3950_extended_services('update',set_service_options('update'),$record);
1001 warn "heres the record to delete $bibid";
1002 my $Zconn = C4::Context->Zconn;
1003 my $p = $Zconn->package();
1004 $p->option(action => "recordDelete");
1005 $p->option(record => $record);
1008 # z3950_extended_services('update',set_service_options('update','recordDelete',$record));
1009 z3950_extended_services('commit');
1014 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
1018 creates an item from a MARC::Record
1025 my ( $dbh,$record,$biblionumber,$biblioitemnumber ) = @_;
1027 # add item in old-DB
1028 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1029 my $item = &MARCmarc2koha( $dbh,$record,$frameworkcode );
1030 # needs old biblionumber and biblioitemnumber
1031 $item->{'biblionumber'} = $biblionumber;
1032 $item->{'biblioitemnumber'}=$biblioitemnumber;
1033 $item->{marc} = $record->as_usmarc();
1034 #warn $item->{marc};
1035 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
1042 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
1053 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
1055 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
1056 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1058 $olditem->{marc} = $record->as_usmarc();
1059 $olditem->{biblionumber} = $biblionumber;
1060 $olditem->{biblioitemnumber} = $biblioitemnumber;
1062 REALmoditem( $dbh, $olditem );
1068 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
1079 my ( $dbh, $bibid, $itemnumber ) = @_;
1080 &REALdelitem( $dbh, $itemnumber );
1081 # &MARCdelitem( $dbh, $bibid, $itemnumber );
1082 # we must now delete the item data from zebra
1086 =head2 REALnewbiblio
1088 $biblionumber = REALnewbiblio($dbh,$biblio);
1092 adds a record in biblio table. Datas are in the hash $biblio.
1099 my ( $dbh, $biblio ) = @_;
1101 $dbh->do('lock tables biblio WRITE');
1102 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1104 my $data = $sth->fetchrow_arrayref;
1105 my $bibnum = $$data[0] + 1;
1108 if ( $biblio->{'seriestitle'} ) { $series = 1 }
1111 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
1112 serial=?, seriestitle=?, notes=?, abstract=?,
1116 $bibnum, $biblio->{'title'},
1117 $biblio->{'author'}, $biblio->{'copyrightdate'},
1118 $biblio->{'serial'}, $biblio->{'seriestitle'},
1119 $biblio->{'notes'}, $biblio->{'abstract'},
1120 $biblio->{'unititle'}
1124 $dbh->do('unlock tables');
1128 =head2 REALmodbiblio
1130 $biblionumber = REALmodbiblio($dbh,$biblio);
1134 modify a record in biblio table. Datas are in the hash $biblio.
1141 my ( $dbh, $biblio ) = @_;
1142 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
1143 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
1144 where biblionumber = ?"
1147 $biblio->{'title'}, $biblio->{'author'},
1148 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
1149 $biblio->{'seriestitle'}, $biblio->{'serial'},
1150 $biblio->{'unititle'}, $biblio->{'notes'},
1151 $biblio->{frameworkcode},
1152 $biblio->{'biblionumber'}
1155 return ( $biblio->{'biblionumber'} );
1158 =head2 REALmodsubtitle
1160 REALmodsubtitle($dbh,$bibnum,$subtitle);
1164 modify subtitles in bibliosubtitle table.
1170 sub REALmodsubtitle {
1171 my ( $dbh, $bibnum, $subtitle ) = @_;
1174 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1175 $sth->execute( $subtitle, $bibnum );
1179 =head2 REALmodaddauthor
1181 REALmodaddauthor($dbh,$bibnum,$author);
1185 adds or modify additional authors
1186 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1192 sub REALmodaddauthor {
1193 my ( $dbh, $bibnum, @authors ) = @_;
1195 # my $dbh = C4Connect;
1197 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1199 $sth->execute($bibnum);
1201 foreach my $author (@authors) {
1202 if ( $author ne '' ) {
1205 "Insert into additionalauthors set author = ?, biblionumber = ?"
1208 $sth->execute( $author, $bibnum );
1213 } # sub modaddauthor
1215 =head2 REALmodsubject
1217 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1221 modify/adds subjects
1226 sub REALmodsubject {
1227 my ( $dbh, $bibnum, $force, @subject ) = @_;
1229 # my $dbh = C4Connect;
1230 my $count = @subject;
1232 for ( my $i = 0 ; $i < $count ; $i++ ) {
1233 $subject[$i] =~ s/^ //g;
1234 $subject[$i] =~ s/ $//g;
1237 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1239 $sth->execute( $subject[$i] );
1241 if ( my $data = $sth->fetchrow_hashref ) {
1244 if ( $force eq $subject[$i] || $force == 1 ) {
1246 # subject not in aut, chosen to force anway
1247 # so insert into cataloguentry so its in auth file
1250 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1253 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1258 "$subject[$i]\n does not exist in the subject authority file";
1261 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1263 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1265 while ( my $data = $sth2->fetchrow_hashref ) {
1266 $error .= "<br>$data->{'catalogueentry'}";
1275 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1276 $sth->execute($bibnum);
1280 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1282 foreach $query (@subject) {
1283 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1292 =head2 REALmodbiblioitem
1294 REALmodbiblioitem($dbh, $biblioitem);
1303 sub REALmodbiblioitem {
1304 my ( $dbh, $biblioitem ) = @_;
1307 my $sth = $dbh->prepare("update biblioitems set number=?,volume=?, volumedate=?, lccn=?,
1308 itemtype=?, url=?, isbn=?, issn=?,
1309 publishercode=?, publicationyear=?, classification=?, dewey=?,
1310 subclass=?, illus=?, pages=?, volumeddesc=?,
1311 notes=?, size=?, place=?, marc=?,
1313 where biblioitemnumber=?");
1314 $sth->execute( $biblioitem->{number}, $biblioitem->{volume}, $biblioitem->{volumedate}, $biblioitem->{lccn},
1315 $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1316 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1317 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1318 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1319 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1321 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1323 z3950_extended_services('update',set_service_options('update'),$record);
1324 z3950_extended_services('commit');
1327 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1330 =head2 REALnewbiblioitem
1332 REALnewbiblioitem($dbh,$biblioitem);
1336 adds a biblioitem ($biblioitem is a hash with the values)
1342 sub REALnewbiblioitem {
1343 my ( $dbh, $biblioitem ) = @_;
1345 $dbh->do("lock tables biblioitems WRITE, biblio WRITE, marc_subfield_structure READ");
1346 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1348 my $biblioitemnumber;
1351 $data = $sth->fetchrow_arrayref;
1352 $biblioitemnumber = $$data[0] + 1;
1354 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1355 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1356 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1357 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1358 my $field=$record->field($biblioitemnumberfield);
1359 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1360 $biblioitem->{marc} = $record->as_usmarc();
1361 $biblioitem->{marcxml} = $record->as_xml();
1363 $sth = $dbh->prepare( "insert into biblioitems set
1364 biblioitemnumber = ?, biblionumber = ?,
1365 volume = ?, number = ?,
1366 classification = ?, itemtype = ?,
1368 issn = ?, dewey = ?,
1369 subclass = ?, publicationyear = ?,
1370 publishercode = ?, volumedate = ?,
1371 volumeddesc = ?, illus = ?,
1372 pages = ?, notes = ?,
1374 marc = ?, place = ?,
1378 $biblioitemnumber, $biblioitem->{'biblionumber'},
1379 $biblioitem->{'volume'}, $biblioitem->{'number'},
1380 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1381 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1382 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1383 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1384 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1385 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1386 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1387 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1388 $biblioitem->{'marc'}, $biblioitem->{'place'},
1389 $biblioitem->{marcxml},
1391 $dbh->do("unlock tables");
1392 z3950_extended_services('update',set_service_options('update'),$record);
1393 z3950_extended_services('commit');
1394 return ($biblioitemnumber);
1397 =head2 REALnewsubtitle
1399 REALnewsubtitle($dbh,$bibnum,$subtitle);
1403 create a new subtitle
1408 sub REALnewsubtitle {
1409 my ( $dbh, $bibnum, $subtitle ) = @_;
1412 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1413 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1419 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1423 create a item. $item is a hash and $barcode the barcode.
1430 my ( $dbh, $item, $barcode ) = @_;
1432 # warn "OLDNEWITEMS";
1434 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE,marc_subfield_structure WRITE');
1435 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1440 $data = $sth->fetchrow_hashref;
1441 $itemnumber = $data->{'max(itemnumber)'} + 1;
1443 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1444 if ( $item->{'loan'} ) {
1445 $item->{'notforloan'} = $item->{'loan'};
1447 $item->{'biblioitemnumber'} = 1;
1448 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1449 if ( $item->{'dateaccessioned'} ) {
1450 $sth = $dbh->prepare( "Insert into items set
1451 itemnumber = ?, biblionumber = ?,
1452 multivolumepart = ?,
1453 biblioitemnumber = ?, barcode = ?,
1454 booksellerid = ?, dateaccessioned = ?,
1455 homebranch = ?, holdingbranch = ?,
1456 price = ?, replacementprice = ?,
1457 replacementpricedate = NOW(), datelastseen = NOW(),
1458 multivolume = ?, stack = ?,
1459 itemlost = ?, wthdrawn = ?,
1460 paidfor = ?, itemnotes = ?,
1461 itemcallnumber =?, notforloan = ?,
1466 $itemnumber, $item->{'biblionumber'},
1467 $item->{'multivolumepart'},
1468 $item->{'biblioitemnumber'},$item->{barcode},
1469 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1470 $item->{'homebranch'}, $item->{'holdingbranch'},
1471 $item->{'price'}, $item->{'replacementprice'},
1472 $item->{multivolume}, $item->{stack},
1473 $item->{itemlost}, $item->{wthdrawn},
1474 $item->{paidfor}, $item->{'itemnotes'},
1475 $item->{'itemcallnumber'}, $item->{'notforloan'},
1478 if ( defined $sth->errstr ) {
1479 $error .= $sth->errstr;
1483 $sth = $dbh->prepare( "Insert into items set
1484 itemnumber = ?, biblionumber = ?,
1485 multivolumepart = ?,
1486 biblioitemnumber = ?, barcode = ?,
1487 booksellerid = ?, dateaccessioned = NOW(),
1488 homebranch = ?, holdingbranch = ?,
1489 price = ?, replacementprice = ?,
1490 replacementpricedate = NOW(), datelastseen = NOW(),
1491 multivolume = ?, stack = ?,
1492 itemlost = ?, wthdrawn = ?,
1493 paidfor = ?, itemnotes = ?,
1494 itemcallnumber =?, notforloan = ?,
1499 $itemnumber, $item->{'biblionumber'},
1500 $item->{'multivolumepart'},
1501 $item->{'biblioitemnumber'},$item->{barcode},
1502 $item->{'booksellerid'},
1503 $item->{'homebranch'}, $item->{'holdingbranch'},
1504 $item->{'price'}, $item->{'replacementprice'},
1505 $item->{multivolume}, $item->{stack},
1506 $item->{itemlost}, $item->{wthdrawn},
1507 $item->{paidfor}, $item->{'itemnotes'},
1508 $item->{'itemcallnumber'}, $item->{'notforloan'},
1511 if ( defined $sth->errstr ) {
1512 $error .= $sth->errstr;
1515 # item stored, now, deal with the marc part...
1516 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1517 where biblio.biblionumber=biblioitems.biblionumber and
1518 biblio.biblionumber=?");
1519 $sth->execute($item->{biblionumber});
1520 if ( defined $sth->errstr ) {
1521 $error .= $sth->errstr;
1523 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1524 warn "ERROR IN REALnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1525 my $record = MARC::File::USMARC::decode($rawmarc);
1526 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1527 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1528 my $itemrecord = MARC::Record->new_from_usmarc($item->{marc});
1530 #warn $itemnumberfield;
1531 #warn $itemrecord->field($itemnumberfield);
1532 my $itemfield = $itemrecord->field($itemnumberfield);
1533 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1534 $record->insert_grouped_field($itemfield);
1535 # save the record into biblioitem
1536 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1537 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1538 if ( defined $sth->errstr ) {
1539 $error .= $sth->errstr;
1541 z3950_extended_services('update',set_service_options('update'),$record);
1542 z3950_extended_services('commit');
1543 $dbh->do('unlock tables');
1544 return ( $itemnumber, $error );
1547 =head2 REALmoditem($dbh,$item);
1558 my ( $dbh, $item ) = @_;
1559 $item->{'bibitemnum'} = 1;
1561 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1562 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1563 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1565 $item->{'barcode'}, $item->{'itemnotes'},
1566 $item->{'itemcallnumber'}, $item->{'notforloan'},
1567 $item->{'location'}, $item->{multivolumepart},
1568 $item->{multivolume}, $item->{stack},
1571 if ( $item->{'lost'} ne '' ) {
1572 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1573 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1574 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1576 $item->{'bibitemnum'}, $item->{'barcode'},
1577 $item->{'itemnotes'}, $item->{'homebranch'},
1578 $item->{'lost'}, $item->{'wthdrawn'},
1579 $item->{'itemcallnumber'}, $item->{'notforloan'},
1580 $item->{'location'}, $item->{multivolumepart},
1581 $item->{multivolume}, $item->{stack},
1584 if ($item->{homebranch}) {
1585 $query.=",homebranch=?";
1586 push @bind, $item->{homebranch};
1588 if ($item->{holdingbranch}) {
1589 $query.=",holdingbranch=?";
1590 push @bind, $item->{holdingbranch};
1593 $query.=" where itemnumber=?";
1594 push @bind,$item->{'itemnum'};
1595 if ( $item->{'replacement'} ne '' ) {
1596 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1598 my $sth = $dbh->prepare($query);
1599 $sth->execute(@bind);
1601 # item stored, now, deal with the marc part...
1602 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1603 where biblio.biblionumber=biblioitems.biblionumber and
1604 biblio.biblionumber=? and
1605 biblioitems.biblioitemnumber=?");
1606 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1607 if ( defined $sth->errstr ) {
1608 $error .= $sth->errstr;
1610 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1611 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1612 my $record = MARC::File::USMARC::decode($rawmarc);
1613 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1614 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1615 # prepare the new item record
1616 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1617 my $itemfield = $itemrecord->field($itemnumberfield);
1618 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1619 # parse all fields fields from the complete record
1620 foreach ($record->field($itemnumberfield)) {
1621 # when the previous field is found, replace by the new one
1622 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1623 $_->replace_with($itemfield);
1626 # $record->insert_grouped_field($itemfield);
1627 # save the record into biblioitem
1628 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1629 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1630 z3950_extended_services('update',set_service_options('update'),$record);
1631 z3950_extended_services('commit');
1632 if ( defined $sth->errstr ) {
1633 $error .= $sth->errstr;
1635 $dbh->do('unlock tables');
1639 =head2 REALdelitem($dbh,$itemnum);
1650 my ( $dbh, $itemnum ) = @_;
1652 # my $dbh=C4Connect;
1653 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1654 $sth->execute($itemnum);
1655 my $data = $sth->fetchrow_hashref;
1657 my $query = "Insert into deleteditems set ";
1659 foreach my $temp ( keys %$data ) {
1660 $query .= "$temp = ?,";
1661 push ( @bind, $data->{$temp} );
1666 $sth = $dbh->prepare($query);
1667 $sth->execute(@bind);
1669 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1670 $sth->execute($itemnum);
1676 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1680 deletes a biblioitem
1681 NOTE : not standard sub name. Should be REALdelbiblioitem()
1687 sub REALdelbiblioitem {
1688 my ( $dbh, $biblioitemnumber ) = @_;
1690 # my $dbh = C4Connect;
1691 my $sth = $dbh->prepare( "Select * from biblioitems
1692 where biblioitemnumber = ?"
1696 $sth->execute($biblioitemnumber);
1698 if ( $results = $sth->fetchrow_hashref ) {
1702 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1703 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1704 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1708 $results->{biblioitemnumber}, $results->{biblionumber},
1709 $results->{volume}, $results->{number},
1710 $results->{classification}, $results->{itemtype},
1711 $results->{isbn}, $results->{issn},
1712 $results->{dewey}, $results->{subclass},
1713 $results->{publicationyear}, $results->{publishercode},
1714 $results->{volumedate}, $results->{volumeddesc},
1715 $results->{timestamp}, $results->{illus},
1716 $results->{pages}, $results->{notes},
1717 $results->{size}, $results->{url},
1721 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1722 $sth2->execute($biblioitemnumber);
1727 # Now delete all the items attached to the biblioitem
1728 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1729 $sth->execute($biblioitemnumber);
1731 while ( my $data = $sth->fetchrow_hashref ) {
1732 my $query = "Insert into deleteditems set ";
1734 foreach my $temp ( keys %$data ) {
1735 $query .= "$temp = ?,";
1736 push ( @bind, $data->{$temp} );
1739 my $sth2 = $dbh->prepare($query);
1740 $sth2->execute(@bind);
1743 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1744 $sth->execute($biblioitemnumber);
1748 } # sub deletebiblioitem
1750 =head2 REALdelbiblio($dbh,$biblio);
1761 my ( $dbh, $biblio ) = @_;
1762 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1763 $sth->execute($biblio);
1764 if ( my $data = $sth->fetchrow_hashref ) {
1766 my $query = "Insert into deletedbiblio set ";
1768 foreach my $temp ( keys %$data ) {
1769 $query .= "$temp = ?,";
1770 push ( @bind, $data->{$temp} );
1773 #replacing the last , by ",?)"
1775 $sth = $dbh->prepare($query);
1776 $sth->execute(@bind);
1778 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1779 $sth->execute($biblio);
1787 $number = itemcount($biblio);
1791 returns the number of items attached to a biblio
1799 my $dbh = C4::Context->dbh;
1802 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1803 $sth->execute($biblio);
1804 my $data = $sth->fetchrow_hashref;
1806 return ( $data->{'count(*)'} );
1811 $biblionumber = newbiblio($biblio);
1815 create a biblio. The parameter is a hash
1823 my $dbh = C4::Context->dbh;
1824 my $bibnum = REALnewbiblio( $dbh, $biblio );
1825 # finds new (MARC bibid
1826 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1827 # my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1828 # MARCaddbiblio( $dbh, $record, $bibnum,'' );
1834 $biblionumber = &modbiblio($biblio);
1838 Update a biblio record.
1840 C<$biblio> is a reference-to-hash whose keys are the fields in the
1841 biblio table in the Koha database. All fields must be present, not
1842 just the ones you wish to change.
1844 C<&modbiblio> updates the record defined by
1845 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1847 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1856 my $dbh = C4::Context->dbh;
1857 my $biblionumber=REALmodbiblio($dbh,$biblio);
1858 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1859 # finds new (MARC bibid
1860 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1861 MARCmodbiblio($dbh,$bibid,$record,"",0);
1862 return($biblionumber);
1865 =head2 &modsubtitle($biblionumber, $subtitle);
1869 Sets the subtitle of a book.
1871 C<$biblionumber> is the biblionumber of the book to modify.
1873 C<$subtitle> is the new subtitle.
1880 my ( $bibnum, $subtitle ) = @_;
1881 my $dbh = C4::Context->dbh;
1882 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1885 =head2 &modaddauthor($biblionumber, $author);
1889 Replaces all additional authors for the book with biblio number
1890 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1891 C<&modaddauthor> deletes all additional authors.
1898 my ( $bibnum, @authors ) = @_;
1899 my $dbh = C4::Context->dbh;
1900 &REALmodaddauthor( $dbh, $bibnum, @authors );
1901 } # sub modaddauthor
1905 $error = &modsubject($biblionumber, $force, @subjects);
1909 $force - a subject to force
1910 $error - Error message, or undef if successful.
1917 my ( $bibnum, $force, @subject ) = @_;
1918 my $dbh = C4::Context->dbh;
1919 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1921 # When MARC is off, ensures that the MARC biblio table gets updated with new
1922 # subjects, of course, it deletes the biblio in marc, and then recreates.
1923 # This check is to ensure that no MARC data exists to lose.
1924 # if (C4::Context->preference("MARC") eq '0'){
1925 # warn "in modSUBJECT";
1926 # my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1927 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1928 # &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1934 =head2 modbibitem($dbh, $biblioitem);
1938 modify a biblioitem. The parameter is a hash
1945 my ($dbh, $biblioitem) = @_;
1946 #my $dbh = C4::Context->dbh;
1947 &REALmodbiblioitem( $dbh, $biblioitem );
1950 =head2 newbiblioitem
1952 $biblioitemnumber = newbiblioitem($biblioitem)
1956 create a biblioitem, the parameter is a hash
1963 my ($dbh, $biblioitem) = @_;
1964 #my $dbh = C4::Context->dbh;
1965 # add biblio information to the hash
1966 my $MARCbiblio = MARCkoha2marcBiblio( $dbh, $biblioitem );
1967 $biblioitem->{marc} = $MARCbiblio->as_usmarc();
1968 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
1969 return ($bibitemnum);
1972 =head2 newsubtitle($biblionumber,$subtitle);
1976 insert a subtitle for $biblionumber biblio
1984 my ( $bibnum, $subtitle ) = @_;
1985 my $dbh = C4::Context->dbh;
1986 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
1991 $errors = newitems($dbh, $item, @barcodes);
1995 insert items ($item is a hash)
2003 my ( $dbh, $item, @barcodes ) = @_;
2004 #my $dbh = C4::Context->dbh;
2008 foreach my $barcode (@barcodes) {
2009 # add items, one by one for each barcode.
2011 $oneitem->{barcode}= $barcode;
2012 my $MARCitem = &MARCkoha2marcItem( $dbh, $oneitem);
2013 $oneitem->{marc} = $MARCitem->as_usmarc;
2014 ( $itemnumber, $error ) = &REALnewitems( $dbh, $oneitem);
2015 # $errors .= $error;
2016 # &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2021 =head2 moditem($dbh,$item);
2025 modify an item ($item is a hash with all item informations)
2033 my ($dbh, $item) = @_;
2034 #my $dbh = C4::Context->dbh;
2035 &REALmoditem( $dbh, $item );
2037 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2039 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2040 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2045 $error = checkitems($count,@barcodes);
2049 check for each @barcode entry that the barcode is not a duplicate
2056 my ( $count, @barcodes ) = @_;
2057 my $dbh = C4::Context->dbh;
2059 my $sth = $dbh->prepare("Select * from items where barcode=?");
2060 for ( my $i = 0 ; $i < $count ; $i++ ) {
2061 $barcodes[$i] = uc $barcodes[$i];
2062 $sth->execute( $barcodes[$i] );
2063 if ( my $data = $sth->fetchrow_hashref ) {
2064 $error .= " Duplicate Barcode: $barcodes[$i]";
2071 =head2 delitem($itemnum);
2075 delete item $itemnum being the item number to delete
2083 my $dbh = C4::Context->dbh;
2084 &REALdelitem( $dbh, $itemnum );
2087 =head2 deletebiblioitem($biblioitemnumber);
2091 delete the biblioitem $biblioitemnumber
2097 sub deletebiblioitem {
2098 my ($biblioitemnumber) = @_;
2099 my $dbh = C4::Context->dbh;
2100 &REALdelbiblioitem( $dbh, $biblioitemnumber );
2101 } # sub deletebiblioitem
2103 =head2 delbiblio($biblionumber)
2107 delete biblio $biblionumber
2115 my $dbh = C4::Context->dbh;
2116 &REALdelbiblio( $dbh, $biblio );
2117 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2118 &MARCdelbiblio( $dbh, $bibid, 0 );
2123 ($count,@results) = getbiblio($biblionumber);
2127 return an array with hash of biblios.
2129 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
2136 my ($biblionumber) = @_;
2137 my $dbh = C4::Context->dbh;
2138 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2140 # || die "Cannot prepare $query\n" . $dbh->errstr;
2144 $sth->execute($biblionumber);
2146 # || die "Cannot execute $query\n" . $sth->errstr;
2147 while ( my $data = $sth->fetchrow_hashref ) {
2148 $results[$count] = $data;
2153 return ( $count, @results );
2158 $data = &bibdata($biblionumber, $type);
2160 Returns information about the book with the given biblionumber.
2162 C<$type> is ignored.
2164 C<&bibdata> returns a reference-to-hash. The keys are the fields in
2165 the C<biblio>, C<biblioitems>, and C<bibliosubtitle> tables in the
2168 In addition, C<$data-E<gt>{subject}> is the list of the book's
2169 subjects, separated by C<" , "> (space, comma, space).
2171 If there are multiple biblioitems with the given biblionumber, only
2172 the first one is considered.
2177 my ($bibnum, $type) = @_;
2178 my $dbh = C4::Context->dbh;
2179 my $sth = $dbh->prepare("Select *, biblioitems.notes AS bnotes, biblio.notes
2181 left join biblioitems on biblioitems.biblionumber = biblio.biblionumber
2182 left join bibliosubtitle on
2183 biblio.biblionumber = bibliosubtitle.biblionumber
2184 left join itemtypes on biblioitems.itemtype=itemtypes.itemtype
2185 where biblio.biblionumber = ?
2187 $sth->execute($bibnum);
2189 $data = $sth->fetchrow_hashref;
2191 # handle management of repeated subtitle
2192 $sth = $dbh->prepare("Select * from bibliosubtitle where biblionumber = ?");
2193 $sth->execute($bibnum);
2195 while (my $dat = $sth->fetchrow_hashref){
2197 $line{subtitle} = $dat->{subtitle};
2198 push @subtitles, \%line;
2200 $data->{subtitles} = \@subtitles;
2202 $sth = $dbh->prepare("Select * from bibliosubject where biblionumber = ?");
2203 $sth->execute($bibnum);
2205 while (my $dat = $sth->fetchrow_hashref){
2207 $line{subject} = $dat->{'subject'};
2208 push @subjects, \%line;
2210 $data->{subjects} = \@subjects;
2212 $sth = $dbh->prepare("Select * from additionalauthors where biblionumber = ?");
2213 $sth->execute($bibnum);
2214 while (my $dat = $sth->fetchrow_hashref){
2215 $data->{'additionalauthors'} .= "$dat->{'author'} - ";
2217 chop $data->{'additionalauthors'};
2218 chop $data->{'additionalauthors'};
2219 chop $data->{'additionalauthors'};
2224 =head2 getbiblioitem
2226 ($count,@results) = getbiblioitem($biblioitemnumber);
2230 return an array with hash of biblioitemss.
2232 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
2239 my ($biblioitemnum) = @_;
2240 my $dbh = C4::Context->dbh;
2241 my $sth = $dbh->prepare( "Select * from biblioitems where
2242 biblioitemnumber = ?"
2247 $sth->execute($biblioitemnum);
2249 while ( my $data = $sth->fetchrow_hashref ) {
2250 $results[$count] = $data;
2255 return ( $count, @results );
2256 } # sub getbiblioitem
2258 =head2 getbiblioitembybiblionumber
2260 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
2264 return an array with hash of biblioitems for the given biblionumber.
2270 sub getbiblioitembybiblionumber {
2271 my ($biblionumber) = @_;
2272 my $dbh = C4::Context->dbh;
2273 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2277 $sth->execute($biblionumber);
2279 while ( my $data = $sth->fetchrow_hashref ) {
2280 $results[$count] = $data;
2285 return ( $count, @results );
2288 =head2 getitemsbybiblioitem
2290 ($count,@results) = getitemsbybiblioitem($biblionumber);
2294 returns an array with hash of items
2300 sub getitemsbybiblioitem {
2301 my ($biblioitemnum) = @_;
2302 my $dbh = C4::Context->dbh;
2303 my $sth = $dbh->prepare( "Select * from items, biblio where
2304 biblio.biblionumber = items.biblionumber and biblioitemnumber
2308 # || die "Cannot prepare $query\n" . $dbh->errstr;
2312 $sth->execute($biblioitemnum);
2314 # || die "Cannot execute $query\n" . $sth->errstr;
2315 while ( my $data = $sth->fetchrow_hashref ) {
2316 $results[$count] = $data;
2321 return ( $count, @results );
2322 } # sub getitemsbybiblioitem
2326 @results = &ItemInfo($env, $biblionumber, $type);
2328 Returns information about books with the given biblionumber.
2330 C<$type> may be either C<intra> or anything else. If it is not set to
2331 C<intra>, then the search will exclude lost, very overdue, and
2336 C<&ItemInfo> returns a list of references-to-hash. Each element
2337 contains a number of keys. Most of them are table items from the
2338 C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
2339 Koha database. Other keys include:
2343 =item C<$data-E<gt>{branchname}>
2345 The name (not the code) of the branch to which the book belongs.
2347 =item C<$data-E<gt>{datelastseen}>
2349 This is simply C<items.datelastseen>, except that while the date is
2350 stored in YYYY-MM-DD format in the database, here it is converted to
2351 DD/MM/YYYY format. A NULL date is returned as C<//>.
2353 =item C<$data-E<gt>{datedue}>
2355 =item C<$data-E<gt>{class}>
2357 This is the concatenation of C<biblioitems.classification>, the book's
2358 Dewey code, and C<biblioitems.subclass>.
2360 =item C<$data-E<gt>{ocount}>
2362 I think this is the number of copies of the book available.
2364 =item C<$data-E<gt>{order}>
2366 If this is set, it is set to C<One Order>.
2373 my ($env,$biblionumber,$type) = @_;
2374 my $dbh = C4::Context->dbh;
2375 my $query = "SELECT *,items.notforloan as itemnotforloan FROM items, biblio, biblioitems
2376 left join itemtypes on biblioitems.itemtype = itemtypes.itemtype
2377 WHERE items.biblionumber = ?
2378 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2379 AND biblio.biblionumber = items.biblionumber";
2380 $query .= " order by items.dateaccessioned desc";
2381 my $sth=$dbh->prepare($query);
2382 $sth->execute($biblionumber);
2385 while (my $data=$sth->fetchrow_hashref){
2387 my $isth=$dbh->prepare("Select issues.*,borrowers.cardnumber from issues,borrowers where itemnumber = ? and returndate is null and issues.borrowernumber=borrowers.borrowernumber");
2388 $isth->execute($data->{'itemnumber'});
2389 if (my $idata=$isth->fetchrow_hashref){
2390 $data->{borrowernumber} = $idata->{borrowernumber};
2391 $data->{cardnumber} = $idata->{cardnumber};
2392 $datedue = format_date($idata->{'date_due'});
2394 if ($datedue eq ''){
2395 my ($restype,$reserves)=C4::Reserves2::CheckReserves($data->{'itemnumber'});
2401 #get branch information.....
2402 my $bsth=$dbh->prepare("SELECT * FROM branches WHERE branchcode = ?");
2403 $bsth->execute($data->{'holdingbranch'});
2404 if (my $bdata=$bsth->fetchrow_hashref){
2405 $data->{'branchname'} = $bdata->{'branchname'};
2407 my $date=format_date($data->{'datelastseen'});
2408 $data->{'datelastseen'}=$date;
2409 $data->{'datedue'}=$datedue;
2410 # get notforloan complete status if applicable
2411 my $sthnflstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.notforloan"');
2412 $sthnflstatus->execute;
2413 my ($authorised_valuecode) = $sthnflstatus->fetchrow;
2414 if ($authorised_valuecode) {
2415 $sthnflstatus = $dbh->prepare("select lib from authorised_values where category=? and authorised_value=?");
2416 $sthnflstatus->execute($authorised_valuecode,$data->{itemnotforloan});
2417 my ($lib) = $sthnflstatus->fetchrow;
2418 $data->{notforloan} = $lib;
2429 ($count, @results) = &bibitems($biblionumber);
2431 Given the biblionumber for a book, C<&bibitems> looks up that book's
2432 biblioitems (different publications of the same book, the audio book
2433 and film versions, etc.).
2435 C<$count> is the number of elements in C<@results>.
2437 C<@results> is an array of references-to-hash; the keys are the fields
2438 of the C<biblioitems> and C<itemtypes> tables of the Koha database. In
2439 addition, C<itemlost> indicates the availability of the item: if it is
2440 "2", then all copies of the item are long overdue; if it is "1", then
2441 all copies are lost; otherwise, there is at least one copy available.
2447 my $dbh = C4::Context->dbh;
2448 my $sth = $dbh->prepare("SELECT biblioitems.*,
2450 MIN(items.itemlost) as itemlost,
2451 MIN(items.dateaccessioned) as dateaccessioned
2452 FROM biblioitems, itemtypes, items
2453 WHERE biblioitems.biblionumber = ?
2454 AND biblioitems.itemtype = itemtypes.itemtype
2455 AND biblioitems.biblioitemnumber = items.biblioitemnumber
2456 GROUP BY items.biblioitemnumber");
2459 $sth->execute($bibnum);
2460 while (my $data = $sth->fetchrow_hashref) {
2461 $results[$count] = $data;
2465 return($count, @results);
2471 $itemdata = &bibitemdata($biblioitemnumber);
2473 Looks up the biblioitem with the given biblioitemnumber. Returns a
2474 reference-to-hash. The keys are the fields from the C<biblio>,
2475 C<biblioitems>, and C<itemtypes> tables in the Koha database, except
2476 that C<biblioitems.notes> is given as C<$itemdata-E<gt>{bnotes}>.
2482 my $dbh = C4::Context->dbh;
2483 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");
2486 $sth->execute($bibitem);
2488 $data = $sth->fetchrow_hashref;
2495 =head2 getbibliofromitemnumber
2497 $item = &getbibliofromitemnumber($env, $dbh, $itemnumber);
2499 Looks up the item with the given itemnumber.
2501 C<$env> and C<$dbh> are ignored.
2503 C<&itemnodata> returns a reference-to-hash whose keys are the fields
2504 from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
2509 sub getbibliofromitemnumber {
2510 my ($env,$dbh,$itemnumber) = @_;
2511 $dbh = C4::Context->dbh;
2512 my $sth=$dbh->prepare("Select * from biblio,items,biblioitems
2513 where items.itemnumber = ?
2514 and biblio.biblionumber = items.biblionumber
2515 and biblioitems.biblioitemnumber = items.biblioitemnumber");
2517 $sth->execute($itemnumber);
2518 my $data=$sth->fetchrow_hashref;
2525 @barcodes = &barcodes($biblioitemnumber);
2527 Given a biblioitemnumber, looks up the corresponding items.
2529 Returns an array of references-to-hash; the keys are C<barcode> and
2532 The returned items include very overdue items, but not lost ones.
2537 #called from request.pl
2538 my ($biblioitemnumber)=@_;
2539 my $dbh = C4::Context->dbh;
2540 my $sth=$dbh->prepare("SELECT barcode, itemlost, holdingbranch FROM items
2541 WHERE biblioitemnumber = ?
2542 AND (wthdrawn <> 1 OR wthdrawn IS NULL)");
2543 $sth->execute($biblioitemnumber);
2546 while (my $data=$sth->fetchrow_hashref){
2547 $barcodes[$i]=$data;
2557 $item = &itemdata($barcode);
2559 Looks up the item with the given barcode, and returns a
2560 reference-to-hash containing information about that item. The keys of
2561 the hash are the fields from the C<items> and C<biblioitems> tables in
2566 sub get_item_from_barcode {
2568 my $dbh = C4::Context->dbh;
2569 my $sth=$dbh->prepare("Select * from items,biblioitems where barcode=?
2570 and items.biblioitemnumber=biblioitems.biblioitemnumber");
2571 $sth->execute($barcode);
2572 my $data=$sth->fetchrow_hashref;
2580 @issues = &itemissues($biblioitemnumber, $biblio);
2582 Looks up information about who has borrowed the bookZ<>(s) with the
2583 given biblioitemnumber.
2585 C<$biblio> is ignored.
2587 C<&itemissues> returns an array of references-to-hash. The keys
2588 include the fields from the C<items> table in the Koha database.
2589 Additional keys include:
2595 If the item is currently on loan, this gives the due date.
2597 If the item is not on loan, then this is either "Available" or
2598 "Cancelled", if the item has been withdrawn.
2602 If the item is currently on loan, this gives the card number of the
2603 patron who currently has the item.
2605 =item C<timestamp0>, C<timestamp1>, C<timestamp2>
2607 These give the timestamp for the last three times the item was
2610 =item C<card0>, C<card1>, C<card2>
2612 The card number of the last three patrons who borrowed this item.
2614 =item C<borrower0>, C<borrower1>, C<borrower2>
2616 The borrower number of the last three patrons who borrowed this item.
2623 my ($bibitem, $biblio)=@_;
2624 my $dbh = C4::Context->dbh;
2625 # FIXME - If this function die()s, the script will abort, and the
2626 # user won't get anything; depending on how far the script has
2627 # gotten, the user might get a blank page. It would be much better
2628 # to at least print an error message. The easiest way to do this
2629 # is to set $SIG{__DIE__}.
2630 my $sth = $dbh->prepare("Select * from items where
2631 items.biblioitemnumber = ?")
2632 || die $dbh->errstr;
2636 $sth->execute($bibitem)
2637 || die $sth->errstr;
2639 while (my $data = $sth->fetchrow_hashref) {
2640 # Find out who currently has this item.
2641 # FIXME - Wouldn't it be better to do this as a left join of
2642 # some sort? Currently, this code assumes that if
2643 # fetchrow_hashref() fails, then the book is on the shelf.
2644 # fetchrow_hashref() can fail for any number of reasons (e.g.,
2645 # database server crash), not just because no items match the
2647 my $sth2 = $dbh->prepare("select * from issues,borrowers
2648 where itemnumber = ?
2649 and returndate is NULL
2650 and issues.borrowernumber = borrowers.borrowernumber");
2652 $sth2->execute($data->{'itemnumber'});
2653 if (my $data2 = $sth2->fetchrow_hashref) {
2654 $data->{'date_due'} = $data2->{'date_due'};
2655 $data->{'card'} = $data2->{'cardnumber'};
2656 $data->{'borrower'} = $data2->{'borrowernumber'};
2658 if ($data->{'wthdrawn'} eq '1') {
2659 $data->{'date_due'} = 'Cancelled';
2661 $data->{'date_due'} = 'Available';
2667 # Find the last 3 people who borrowed this item.
2668 $sth2 = $dbh->prepare("select * from issues, borrowers
2669 where itemnumber = ?
2670 and issues.borrowernumber = borrowers.borrowernumber
2671 and returndate is not NULL
2672 order by returndate desc,timestamp desc") || die $dbh->errstr;
2673 $sth2->execute($data->{'itemnumber'}) || die $sth2->errstr;
2674 for (my $i2 = 0; $i2 < 2; $i2++) { # FIXME : error if there is less than 3 pple borrowing this item
2675 if (my $data2 = $sth2->fetchrow_hashref) {
2676 $data->{"timestamp$i2"} = $data2->{'timestamp'};
2677 $data->{"card$i2"} = $data2->{'cardnumber'};
2678 $data->{"borrower$i2"} = $data2->{'borrowernumber'};
2683 $results[$i] = $data;
2693 ($count, $subjects) = &getsubject($biblionumber);
2695 Looks up the subjects of the book with the given biblionumber. Returns
2696 a two-element list. C<$subjects> is a reference-to-array, where each
2697 element is a subject of the book, and C<$count> is the number of
2698 elements in C<$subjects>.
2704 my $dbh = C4::Context->dbh;
2705 my $sth=$dbh->prepare("Select * from bibliosubject where biblionumber=?");
2706 $sth->execute($bibnum);
2709 while (my $data=$sth->fetchrow_hashref){
2714 return($i,\@results);
2719 ($count, $authors) = &getaddauthor($biblionumber);
2721 Looks up the additional authors for the book with the given
2724 Returns a two-element list. C<$authors> is a reference-to-array, where
2725 each element is an additional author, and C<$count> is the number of
2726 elements in C<$authors>.
2732 my $dbh = C4::Context->dbh;
2733 my $sth=$dbh->prepare("Select * from additionalauthors where biblionumber=?");
2734 $sth->execute($bibnum);
2737 while (my $data=$sth->fetchrow_hashref){
2742 return($i,\@results);
2748 ($count, $subtitles) = &getsubtitle($biblionumber);
2750 Looks up the subtitles for the book with the given biblionumber.
2752 Returns a two-element list. C<$subtitles> is a reference-to-array,
2753 where each element is a subtitle, and C<$count> is the number of
2754 elements in C<$subtitles>.
2760 my $dbh = C4::Context->dbh;
2761 my $sth=$dbh->prepare("Select * from bibliosubtitle where biblionumber=?");
2762 $sth->execute($bibnum);
2765 while (my $data=$sth->fetchrow_hashref){
2770 return($i,\@results);
2776 ($count, @websites) = &getwebsites($biblionumber);
2778 Looks up the web sites pertaining to the book with the given
2781 C<$count> is the number of elements in C<@websites>.
2783 C<@websites> is an array of references-to-hash; the keys are the
2784 fields from the C<websites> table in the Koha database.
2787 #FIXME : could maybe be deleted. Otherwise, would be better in a Websites.pm package
2788 #(with add / modify / delete subs)
2791 my ($biblionumber) = @_;
2792 my $dbh = C4::Context->dbh;
2793 my $sth = $dbh->prepare("Select * from websites where biblionumber = ?");
2797 $sth->execute($biblionumber);
2798 while (my $data = $sth->fetchrow_hashref) {
2799 # FIXME - The URL scheme shouldn't be stripped off, at least
2800 # not here, since it's part of the URL, and will be useful in
2801 # constructing a link to the site. If you don't want the user
2802 # to see the "http://" part, strip that off when building the
2804 $data->{'url'} =~ s/^http:\/\///; # FIXME - Leaning toothpick
2806 $results[$count] = $data;
2811 return($count, @results);
2814 =head2 getwebbiblioitems
2816 ($count, @results) = &getwebbiblioitems($biblionumber);
2818 Given a book's biblionumber, looks up the web versions of the book
2819 (biblioitems with itemtype C<WEB>).
2821 C<$count> is the number of items in C<@results>. C<@results> is an
2822 array of references-to-hash; the keys are the items from the
2823 C<biblioitems> table of the Koha database.
2827 sub getwebbiblioitems {
2828 my ($biblionumber) = @_;
2829 my $dbh = C4::Context->dbh;
2830 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?
2831 and itemtype = 'WEB'");
2835 $sth->execute($biblionumber);
2836 while (my $data = $sth->fetchrow_hashref) {
2837 $data->{'url'} =~ s/^http:\/\///;
2838 $results[$count] = $data;
2843 return($count, @results);
2844 } # sub getwebbiblioitems
2847 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2848 my $NSE = '\x89'; # NSE : Non Sorting Block end
2849 # handles non sorting blocks
2853 s/[ ]{0,1}$NSE/) /gm;
2860 my $dbh = C4::Context->dbh;
2861 my $result = MARCmarc2koha($dbh,$record,'');
2863 my ($biblionumber,$bibid,$title);
2864 # search duplicate on ISBN, easy and fast...
2865 if ($result->{isbn}) {
2866 $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=?");
2867 $sth->execute($result->{'isbn'});
2868 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2869 return $biblionumber,$bibid,$title if ($biblionumber);
2871 # a more complex search : build a request for SearchMarc::catalogsearch()
2872 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2873 # search on biblio.title
2874 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2875 if ($record->field($tag)) {
2876 if ($record->field($tag)->subfields($subfield)) {
2877 push @tags, "'".$tag.$subfield."'";
2878 push @and_or, "and";
2879 push @excluding, "";
2880 push @operator, "contains";
2881 push @value, $record->field($tag)->subfield($subfield);
2882 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2885 # ... and on biblio.author
2886 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2887 if ($record->field($tag)) {
2888 if ($record->field($tag)->subfields($subfield)) {
2889 push @tags, "'".$tag.$subfield."'";
2890 push @and_or, "and";
2891 push @excluding, "";
2892 push @operator, "contains";
2893 push @value, $record->field($tag)->subfield($subfield);
2894 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2897 # ... and on publicationyear.
2898 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2899 if ($record->field($tag)) {
2900 if ($record->field($tag)->subfields($subfield)) {
2901 push @tags, "'".$tag.$subfield."'";
2902 push @and_or, "and";
2903 push @excluding, "";
2904 push @operator, "=";
2905 push @value, $record->field($tag)->subfield($subfield);
2906 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2910 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2911 if ($record->field($tag)) {
2912 if ($record->field($tag)->subfields($subfield)) {
2913 push @tags, "'".$tag.$subfield."'";
2914 push @and_or, "and";
2915 push @excluding, "";
2916 push @operator, "=";
2917 push @value, $record->field($tag)->subfield($subfield);
2918 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2921 # ... and on publisher.
2922 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2923 if ($record->field($tag)) {
2924 if ($record->field($tag)->subfields($subfield)) {
2925 push @tags, "'".$tag.$subfield."'";
2926 push @and_or, "and";
2927 push @excluding, "";
2928 push @operator, "=";
2929 push @value, $record->field($tag)->subfield($subfield);
2930 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2933 # ... and on volume.
2934 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2935 if ($record->field($tag)) {
2936 if ($record->field($tag)->subfields($subfield)) {
2937 push @tags, "'".$tag.$subfield."'";
2938 push @and_or, "and";
2939 push @excluding, "";
2940 push @operator, "=";
2941 push @value, $record->field($tag)->subfield($subfield);
2942 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2946 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2947 # there is at least 1 result => return the 1st one
2949 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2950 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2952 # no result, returns nothing
2959 if(substr($isbn, 0, 1) <=7) {
2960 $seg1 = substr($isbn, 0, 1);
2961 } elsif(substr($isbn, 0, 2) <= 94) {
2962 $seg1 = substr($isbn, 0, 2);
2963 } elsif(substr($isbn, 0, 3) <= 995) {
2964 $seg1 = substr($isbn, 0, 3);
2965 } elsif(substr($isbn, 0, 4) <= 9989) {
2966 $seg1 = substr($isbn, 0, 4);
2968 $seg1 = substr($isbn, 0, 5);
2970 my $x = substr($isbn, length($seg1));
2972 if(substr($x, 0, 2) <= 19) {
2973 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2974 $seg2 = substr($x, 0, 2);
2975 } elsif(substr($x, 0, 3) <= 699) {
2976 $seg2 = substr($x, 0, 3);
2977 } elsif(substr($x, 0, 4) <= 8399) {
2978 $seg2 = substr($x, 0, 4);
2979 } elsif(substr($x, 0, 5) <= 89999) {
2980 $seg2 = substr($x, 0, 5);
2981 } elsif(substr($x, 0, 6) <= 9499999) {
2982 $seg2 = substr($x, 0, 6);
2984 $seg2 = substr($x, 0, 7);
2986 my $seg3=substr($x,length($seg2));
2987 $seg3=substr($seg3,0,length($seg3)-1) ;
2988 my $seg4 = substr($x, -1, 1);
2989 return "$seg1-$seg2-$seg3-$seg4";
2993 END { } # module clean-up code here (global destructor)
2999 Koha Developement team <info@koha.org>
3001 Paul POULAIN paul.poulain@free.fr
3007 # Revision 1.164 2006/03/29 01:56:25 rangi
3008 # Delete isnt working using the extended services method
3010 # Revision 1.163 2006/03/28 23:05:08 rangi
3011 # Delete working now
3013 # Revision 1.162 2006/03/13 23:12:44 rangi
3014 # Adding commits, so that changes stick
3016 # Revision 1.161 2006/03/10 02:40:38 kados
3017 # syncing MARChtml2xml wtih rel_2_2, removing unused MARChtml2marc
3019 # Revision 1.160 2006/03/07 22:00:18 kados
3020 # adding support for 'delete' function
3022 # Revision 1.159 2006/03/07 21:54:47 rangi
3023 # Starting work on deletes
3025 # Revision 1.158 2006/03/06 02:45:41 kados
3026 # Adding fixes to MARC editor to HEAD
3028 # Revision 1.157 2006/03/01 03:07:54 kados
3029 # rollback ... by accident I committed a rel_2_2 Biblio.pm
3031 # Revision 1.155 2006/02/27 01:08:31 kados
3032 # Removing 'our Zconn' from top...
3034 # Revision 1.154 2006/02/26 00:08:20 kados
3035 # moving all $Zconn s to z3950_extended_services (currently, nothing
3038 # Revision 1.153 2006/02/25 22:39:10 kados
3039 # Another purely documentation commit. Just changing formatting to ease
3042 # Revision 1.152 2006/02/25 21:17:20 kados
3043 # Purely documentation change: converted all =head2 entries to use function
3044 # name as title rather than usage as title
3046 # Revision 1.151 2006/02/25 21:02:20 kados
3048 # Further cleanup, convering new routines to 4-chars
3050 # Revision 1.150 2006/02/25 20:49:15 kados
3051 # Better documentation, added warning if serviceType is 'drop' since it's
3052 # not supported in Zebra.
3054 # Revision 1.149 2006/02/25 20:30:32 kados
3055 # IMPORTANT: Paul, I've removed the decode_char routine because it's no
3056 # longer necessary. If we need to convert from MARC-8 for display, we should:
3059 # 2. do it with MARC::Charset
3061 # If you still need it, let me know and I'll put it back in.
3063 # Revision 1.148 2006/02/25 19:23:01 kados
3064 # cleaning up POD docs, deleting zebra_create as it's no longer used (
3065 # replaced by z3950_extended_services).
3067 # Revision 1.147 2006/02/25 19:09:59 kados
3068 # readding some lost subs
3070 # Revision 1.145 2006/02/22 01:02:39 kados
3071 # Replacing all calls to zebra_update with calls to
3072 # z3950_extended_services. More work coming, but it's
3075 # Revision 1.144 2006/02/20 14:22:38 kados
3078 # Revision 1.143 2006/02/20 13:26:11 kados
3079 # A new subroutine to handle Z39.50 extended services. You pass it a
3080 # connection object, service type, service options, and a record, and
3081 # it performs the service and handles any exception found.
3083 # Revision 1.142 2006/02/16 20:49:56 kados
3084 # destroy a connection after we're done -- we really should just have one
3085 # connection object and not destroy it until the whole transaction is
3086 # finished -- but this will do for now
3088 # Revision 1.141 2006/02/16 19:47:22 rangi
3089 # Trying to error trap a little more.
3091 # Revision 1.140 2006/02/14 21:36:03 kados
3092 # adding a 'use ZOOM' to biblio.pm, needed for non-mod_perl install.
3093 # also adding diagnostic error if not able to connect to Zebra
3095 # Revision 1.139 2006/02/14 19:53:25 rangi
3096 # Just a little missing my
3098 # Seems to be working great Paul, and I like what you did with zebradb
3100 # Revision 1.138 2006/02/14 11:25:22 tipaul
3101 # road to 3.0 : updating a biblio in zebra seems to work. Still working on it, there are probably some bugs !
3103 # Revision 1.137 2006/02/13 16:34:26 tipaul
3104 # fixing some warnings (perl -w should be quiet)
3106 # Revision 1.136 2006/01/10 17:01:29 tipaul
3107 # adding a XMLgetbiblio in Biblio.pm (1st draft, to use with zebra)
3109 # Revision 1.135 2006/01/06 16:39:37 tipaul
3110 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3111 # Seems not to break too many things, but i'm probably wrong here.
3112 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3114 # - removing useless directories (koha-html and koha-plucene)
3116 # Revision 1.134 2006/01/04 15:54:55 tipaul
3117 # utf8 is a : go for beta test in HEAD.
3118 # some explanations :
3119 # - 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.
3120 # - *-top.inc will show the pages in utf8
3121 # - 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.
3122 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3124 # Revision 1.133 2005/12/12 14:25:51 thd
3127 # Reverse array filled with elements from repeated subfields
3128 # to avoid last to first concatenation of elements in Koha DB.-
3130 # Revision 1.132 2005-10-26 09:12:33 tipaul
3131 # big commit, still breaking things...
3133 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3134 # * code cleaning (cleaning warnings from perl -w) continued
3136 # Revision 1.131 2005/09/22 10:01:45 tipaul
3137 # see mail on koha-devel : code cleaning on Search.pm + normalizing API + use of biblionumber everywhere (instead of bn, biblio, ...)
3139 # Revision 1.130 2005/09/02 14:34:14 tipaul
3140 # continuing the work to move to zebra. Begin of work for MARC=OFF support.
3141 # IMPORTANT NOTE : the MARCkoha2marc sub API has been modified. Instead of biblionumber & biblioitemnumber, it now gets a hash.
3142 # The sub is used only in Biblio.pm, so the API change should be harmless (except for me, but i'm aware ;-) )
3144 # Revision 1.129 2005/08/12 13:50:31 tipaul
3145 # removing useless sub declarations
3147 # Revision 1.128 2005/08/11 16:12:47 tipaul
3148 # Playing with the zebra...
3150 # * go to koha cvs home directory
3151 # * in misc/zebra there is a unimarc directory. I suggest that marc21 libraries create a marc21 directory
3152 # * put your zebra.cfg files here & create your database.
3153 # * from koha cvs home directory, ln -s misc/zebra/marc21 zebra (I mean create a symbolic link to YOUR zebra directory)
3154 # * now, everytime you add/modify a biblio/item your zebra DB is updated correctly.
3157 # * this uses a system call in perl. CPU consumming, but we are waiting for indexdata Perl/zoom
3158 # * deletion still not work
3159 # * UNIMARC zebra config files are provided in misc/zebra/unimarc directory. The most important line being :
3161 # recordId: (bib1,Local-number)
3165 # elm 090 Local-number -
3166 # elm 090/? Local-number -
3167 # elm 090/?/9 Local-number !:w
3169 # (090$9 being the field mapped to biblio.biblionumber in Koha)
3171 # Revision 1.127 2005/08/11 14:37:32 tipaul
3173 # * removing useless subs
3174 # * removing some subs that are also elsewhere
3175 # * 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)
3177 # Revision 1.126 2005/08/11 09:13:28 tipaul
3178 # just removing useless subs (a lot !!!) for code cleaning
3180 # Revision 1.125 2005/08/11 09:00:07 tipaul
3181 # Ok guys, this time, it seems that item add and modif begin working as expected...
3182 # Still a lot of bugs to fix, of course
3184 # Revision 1.124 2005/08/10 10:21:15 tipaul
3185 # continuing the road to zebra :
3186 # - the biblio add begins to work.
3187 # - the biblio modif begins to work.
3189 # (still without doing anything on zebra)
3190 # (no new change in updatedatabase)
3192 # Revision 1.123 2005/08/09 14:10:28 tipaul
3193 # 1st commit to go to zebra.
3194 # don't update your cvs if you want to have a working head...
3196 # this commit contains :
3197 # * 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...
3198 # * 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.
3199 # * other files : get rid of bibid and use biblionumber instead.
3202 # * does not do anything on zebra yet.
3203 # * if you rename marc_subfield_table, you can't search anymore.
3204 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3205 # * 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 ;-) )
3207 # 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
3208 # 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.
3210 # tipaul cutted previous commit notes