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
25 use MARC::File::USMARC;
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
36 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
37 # as the old-style API and the NEW one are the only public functions.
40 &updateBiblio &updateBiblioItem &updateItem
41 &itemcount &newbiblio &newbiblioitem
42 &newsubject &newsubtitle
43 &modbiblio &checkitems
45 &modsubtitle &modsubject &modaddauthor &moditem
46 &delitem &deletebiblioitem &delbiblio
48 &getbiblioitembybiblionumber
49 &getbiblioitem &getitemsbybiblioitem
51 &newcompletebiblioitem
53 &MARCfind_marc_from_kohafield
54 &MARCfind_frameworkcode
55 &find_biblioitemnumber
58 &NEWnewbiblio &NEWnewitem
59 &NEWmodbiblio &NEWmoditem
60 &NEWdelbiblio &NEWdelitem
61 &NEWmodbiblioframework
63 &MARCkoha2marcBiblio &MARCmarc2koha
64 &MARCkoha2marcItem &MARChtml2marc
65 &MARCgetbiblio &MARCgetitem
74 C4::Biblio - acquisition, catalog management functions
78 ( lot of changes for Koha 3.0)
80 Koha 1.2 and previous version used a specific API to manage biblios. This API uses old-DB style parameters.
81 They are based on a hash, and store data in biblio/biblioitems/items tables (plus additionalauthors, bibliosubject and bibliosubtitle where applicable)
83 In Koha 2.0, we introduced a MARC-DB.
85 In Koha 3.0 we removed this MARC-DB for search as we wanted to use Zebra as search system.
87 So in Koha 3.0, saving a record means :
88 - storing the raw marc record (iso2709) in biblioitems.marc field. It contains both biblio & items informations.
89 - storing the "decoded information" in biblio/biblioitems/items as previously.
90 - using zebra to manage search & indexing on the MARC datas.
92 In Koha, there is a systempreference saying "MARC=ON" or "MARC=OFF"
94 * MARC=ON : when MARC=ON, koha uses a MARC::Record object (in sub parameters). Saving informations in the DB means :
95 - transform the MARC record into a hash
96 - add the raw marc record into the hash
97 - store them & update zebra
99 * MARC=OFF : when MARC=OFF, koha uses a hash object (in sub parameters). Saving informations in the DB means :
100 - transform the hash into a MARC record
101 - add the raw marc record into the hash
102 - store them and update zebra
105 That's why we need 3 types of subs :
109 all I<subs beginning by REAL> does 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
111 =head2 NEWxxx related subs
115 all I<subs beginning by NEW> use MARC::Record as parameters. it's the API that MUST be used in MARC acquisition system. They just create the hash, add it the raw marc record. Then, they call REALxxx sub.
117 all subs requires/use $dbh as 1st parameter and a MARC::Record object as 2nd parameter. they sometimes requires another parameter.
121 =head2 something_elsexxx related subs
125 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 calls REAL subs.
127 all subs requires/use $dbh as 1st parameter and a hash as 2nd parameter.
136 =head2 @tagslib = &MARCgettagslib($dbh,1|0,$frameworkcode);
140 2nd param is 1 for liblibrarian and 0 for libopac
141 $frameworkcode contains the framework reference. If empty or does not exist, the default one is used
143 returns a hash with all values for all fields and subfields for a given MARC framework :
144 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
146 ->{mandatory} = $mandatory;
147 ->{repeatable} = $repeatable;
148 ->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
150 ->{mandatory} = $mandatory;
151 ->{repeatable} = $repeatable;
152 ->{authorised_value} = $authorised_value;
153 ->{authtypecode} = $authtypecode;
154 ->{value_builder} = $value_builder;
155 ->{kohafield} = $kohafield;
156 ->{seealso} = $seealso;
157 ->{hidden} = $hidden;
166 my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
167 $frameworkcode = "" unless $frameworkcode;
169 my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
171 # check that framework exists
174 "select count(*) from marc_tag_structure where frameworkcode=?");
175 $sth->execute($frameworkcode);
176 my ($total) = $sth->fetchrow;
177 $frameworkcode = "" unless ( $total > 0 );
180 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
182 $sth->execute($frameworkcode);
183 my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
185 while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
186 $res->{$tag}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
187 $res->{$tab}->{tab} = ""; # XXX
188 $res->{$tag}->{mandatory} = $mandatory;
189 $res->{$tag}->{repeatable} = $repeatable;
194 "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"
196 $sth->execute($frameworkcode);
199 my $authorised_value;
209 ( $tag, $subfield, $liblibrarian, , $libopac, $tab,
210 $mandatory, $repeatable, $authorised_value, $authtypecode,
211 $value_builder, $kohafield, $seealso, $hidden,
216 $res->{$tag}->{$subfield}->{lib} = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
217 $res->{$tag}->{$subfield}->{tab} = $tab;
218 $res->{$tag}->{$subfield}->{mandatory} = $mandatory;
219 $res->{$tag}->{$subfield}->{repeatable} = $repeatable;
220 $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
221 $res->{$tag}->{$subfield}->{authtypecode} = $authtypecode;
222 $res->{$tag}->{$subfield}->{value_builder} = $value_builder;
223 $res->{$tag}->{$subfield}->{kohafield} = $kohafield;
224 $res->{$tag}->{$subfield}->{seealso} = $seealso;
225 $res->{$tag}->{$subfield}->{hidden} = $hidden;
226 $res->{$tag}->{$subfield}->{isurl} = $isurl;
227 $res->{$tag}->{$subfield}->{link} = $link;
232 =head2 ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
236 finds MARC tag and subfield for a given kohafield
237 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
243 sub MARCfind_marc_from_kohafield {
244 my ( $dbh, $kohafield,$frameworkcode ) = @_;
245 return 0, 0 unless $kohafield;
246 my $relations = C4::Context->marcfromkohafield;
247 return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
250 =head2 $MARCRecord = &MARCgetbiblio($dbh,$biblionumber);
254 Returns a MARC::Record for the biblio $biblionumber.
260 # Returns MARC::Record of the biblio passed in parameter.
261 my ( $dbh, $biblionumber ) = @_;
262 my $sth = $dbh->prepare('select marc from biblioitems where biblionumber=?');
263 $sth->execute($biblionumber);
264 my ($marc) = $sth->fetchrow;
265 my $record = MARC::File::USMARC::decode($marc);
269 =head2 $MARCrecord = &MARCgetitem($dbh,$biblionumber);
273 Returns a MARC::Record with all items of biblio # $biblionumber
281 my ( $dbh, $biblionumber, $itemnumber ) = @_;
282 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
283 # get the complete MARC record
284 my $sth = $dbh->prepare("select marc from biblioitems where biblionumber=?");
285 $sth->execute($biblionumber);
286 my ($rawmarc) = $sth->fetchrow;
287 my $record = MARC::File::USMARC::decode($rawmarc);
288 # now, find the relevant itemnumber
289 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
290 # prepare the new item record
291 my $itemrecord = MARC::Record->new();
292 # parse all fields fields from the complete record
293 foreach ($record->field($itemnumberfield)) {
294 # when the item field is found, save it
295 if ($_->subfield($itemnumbersubfield) == $itemnumber) {
296 $itemrecord->append_fields($_);
303 =head2 sub find_biblioitemnumber($dbh,$biblionumber);
307 Returns the 1st biblioitemnumber related to $biblionumber. When MARC=ON we should have 1 biblionumber = 1 and only 1 biblioitemnumber
308 This sub is useless when MARC=OFF
313 sub find_biblioitemnumber {
314 my ( $dbh, $biblionumber ) = @_;
315 my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
316 $sth->execute($biblionumber);
317 my ($biblioitemnumber) = $sth->fetchrow;
318 return $biblioitemnumber;
321 =head2 $frameworkcode = MARCfind_frameworkcode($dbh,$biblionumber);
325 returns the framework of a given biblio
331 sub MARCfind_frameworkcode {
332 my ( $dbh, $biblionumber ) = @_;
333 my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
334 $sth->execute($biblionumber);
335 my ($frameworkcode) = $sth->fetchrow;
336 return $frameworkcode;
339 =head2 $MARCRecord = &MARCkoha2marcBiblio($dbh,$biblionumber,biblioitemnumber);
343 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem :
344 all entries of the hash are transformed into their matching MARC field/subfield.
350 sub MARCkoha2marcBiblio {
352 # this function builds partial MARC::Record from the old koha-DB fields
353 my ( $dbh, $biblionumber, $biblioitemnumber ) = @_;
356 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
358 my $record = MARC::Record->new();
360 #--- if bibid, then retrieve old-style koha data
361 if ( $biblionumber > 0 ) {
364 "select biblionumber,author,title,unititle,notes,abstract,serial,seriestitle,copyrightdate,timestamp
365 from biblio where biblionumber=?"
367 $sth2->execute($biblionumber);
368 my $row = $sth2->fetchrow_hashref;
370 foreach $code ( keys %$row ) {
371 if ( $row->{$code} ) {
372 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $code,
378 #--- if biblioitem, then retrieve old-style koha data
379 if ( $biblioitemnumber > 0 ) {
382 " SELECT biblioitemnumber,biblionumber,volume,number,classification,
383 itemtype,url,isbn,issn,dewey,subclass,publicationyear,publishercode,
384 volumedate,volumeddesc,timestamp,illus,pages,notes AS bnotes,size,place
386 WHERE biblioitemnumber=?
389 $sth2->execute($biblioitemnumber);
390 my $row = $sth2->fetchrow_hashref;
392 foreach $code ( keys %$row ) {
393 if ( $row->{$code} ) {
394 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $code,
400 # other fields => additional authors, subjects, subtitles
403 " SELECT author FROM additionalauthors WHERE biblionumber=?");
404 $sth2->execute($biblionumber);
405 while ( my $row = $sth2->fetchrow_hashref ) {
406 &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author",
407 $row->{'author'},'' );
410 $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
411 $sth2->execute($biblionumber);
412 while ( my $row = $sth2->fetchrow_hashref ) {
413 &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject",
414 $row->{'subject'},'' );
418 " SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
419 $sth2->execute($biblionumber);
420 while ( my $row = $sth2->fetchrow_hashref ) {
421 &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
422 $row->{'subtitle'},'' );
427 =head2 $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
429 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB items :
430 all entries of the hash are transformed into their matching MARC field/subfield.
438 sub MARCkoha2marcItem {
440 # this function builds partial MARC::Record from the old koha-DB fields
441 my ( $dbh, $biblionumber, $itemnumber ) = @_;
443 # my $dbh=&C4Connect;
446 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
448 my $record = MARC::Record->new();
450 #--- if item, then retrieve old-style koha data
451 if ( $itemnumber > 0 ) {
453 # print STDERR "prepare $biblionumber,$itemnumber\n";
456 "SELECT itemnumber,biblionumber,multivolumepart,biblioitemnumber,barcode,dateaccessioned,
457 booksellerid,homebranch,price,replacementprice,replacementpricedate,datelastborrowed,
458 datelastseen,multivolume,stack,notforloan,itemlost,wthdrawn,itemcallnumber,issues,renewals,
459 reserves,restricted,binding,itemnotes,holdingbranch,timestamp
463 $sth2->execute($itemnumber);
464 my $row = $sth2->fetchrow_hashref;
466 foreach $code ( keys %$row ) {
467 if ( $row->{$code} ) {
468 &MARCkoha2marcOnefield( $sth, $record, "items." . $code,
476 =head2 MARCkoha2marcOnefield
480 This sub is for internal use only, used by koha2marcBiblio & koha2marcItem
486 sub MARCkoha2marcOnefield {
487 my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
490 $sth->execute($frameworkcode,$kohafieldname);
491 if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
492 if ( $record->field($tagfield) ) {
493 my $tag = $record->field($tagfield);
495 $tag->add_subfields( $tagsubfield, $value );
496 $record->delete_field($tag);
497 $record->add_fields($tag);
501 $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
507 =head2 $MARCrecord = MARChtml2marc($dbh,$rtags,$rsubfields,$rvalues,%indicators);
511 transforms the parameters (coming from HTML form) into a MARC::Record
512 parameters with r are references to arrays.
514 FIXME : should be improved for 3.0, to avoid having 4 differents arrays
521 my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
523 my $record = MARC::Record->new();
524 # my %subfieldlist=();
525 my $prevvalue; # if tag <10
526 my $field; # if tag >=10
527 for (my $i=0; $i< @$rtags; $i++) {
528 next unless @$rvalues[$i];
529 # rebuild MARC::Record
530 # warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
531 if (@$rtags[$i] ne $prevtag) {
534 if ($prevtag ne '000') {
535 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
537 $record->leader($prevvalue);
542 $record->add_fields($field);
545 $indicators{@$rtags[$i]}.=' ';
546 if (@$rtags[$i] <10) {
547 $prevvalue= @$rvalues[$i];
551 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
552 # warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
554 $prevtag = @$rtags[$i];
556 if (@$rtags[$i] <10) {
557 $prevvalue=@$rvalues[$i];
559 if (length(@$rvalues[$i])>0) {
560 $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
561 # warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
564 $prevtag= @$rtags[$i];
567 # the last has not been included inside the loop... do it now !
568 $record->add_fields($field) if $field;
569 # warn "HTML2MARC=".$record->as_formatted;
574 =head2 $hash = &MARCmarc2koha($dbh,$MARCRecord);
578 builds a hash with old-db datas from a MARC::Record
585 my ($dbh,$record,$frameworkcode) = @_;
586 my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
588 my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
591 while (($field)=$sth2->fetchrow) {
592 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
594 $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
596 while (($field)=$sth2->fetchrow) {
597 if ($field eq 'notes') { $field = 'bnotes'; }
598 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
600 $sth2=$dbh->prepare("SHOW COLUMNS from items");
602 while (($field)=$sth2->fetchrow) {
603 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
605 # additional authors : specific
606 $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
607 $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
608 # modify copyrightdate to keep only the 1st year found
609 my $temp = $result->{'copyrightdate'};
610 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
612 $result->{'copyrightdate'} = $1;
613 } else { # if no cYYYY, get the 1st date.
614 $temp =~ m/(\d\d\d\d)/;
615 $result->{'copyrightdate'} = $1;
617 # modify publicationyear to keep only the 1st year found
618 $temp = $result->{'publicationyear'};
619 $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
621 $result->{'publicationyear'} = $1;
622 } else { # if no cYYYY, get the 1st date.
623 $temp =~ m/(\d\d\d\d)/;
624 $result->{'publicationyear'} = $1;
629 sub MARCmarc2kohaOneField {
631 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
632 my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
633 # warn "kohatable / $kohafield / $result / ";
637 ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
638 foreach my $field ( $record->field($tagfield) ) {
639 if ($field->tag()<10) {
640 if ($result->{$kohafield}) {
641 $result->{$kohafield} .= " | ".$field->data();
643 $result->{$kohafield} = $field->data();
646 if ( $field->subfields ) {
647 my @subfields = $field->subfields();
648 foreach my $subfieldcount ( 0 .. $#subfields ) {
649 if ($subfields[$subfieldcount][0] eq $subfield) {
650 if ( $result->{$kohafield} ) {
651 $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
654 $result->{$kohafield} = $subfields[$subfieldcount][1];
661 # warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
665 =head2 ($biblionumber,$biblioitemnumber) = NEWnewbibilio($dbh,$MARCRecord,$frameworkcode);
669 creates a biblio from a MARC::Record.
676 my ( $dbh, $record, $frameworkcode ) = @_;
678 my $biblioitemnumber;
679 my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
680 $olddata->{frameworkcode} = $frameworkcode;
681 $biblionumber = REALnewbiblio( $dbh, $olddata );
682 $olddata->{biblionumber} = $biblionumber;
683 # add biblionumber into the MARC record (it's the ID for zebra)
684 my ( $tagfield, $tagsubfield ) =
685 MARCfind_marc_from_kohafield( $dbh, "biblio.biblionumber",$frameworkcode );
689 $newfield = MARC::Field->new(
690 $tagfield, $biblionumber,
693 $newfield = MARC::Field->new(
694 $tagfield, '', '', "$tagsubfield" => $biblionumber,
697 # drop old field (just in case it already exist and create new one...
698 my $old_field = $record->field($tagfield);
699 $record->delete_field($old_field);
700 $record->add_fields($newfield);
702 #create the marc entry, that stores the rax marc record in Koha 3.0
703 $olddata->{marc} = $record->as_usmarc();
704 $olddata->{marcxml} = $record->as_xml();
705 # and create biblioitem, that's all folks !
706 $biblioitemnumber = REALnewbiblioitem( $dbh, $olddata );
708 # search subtiles, addiauthors and subjects
709 ( $tagfield, $tagsubfield ) =
710 MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
711 my @addiauthfields = $record->field($tagfield);
712 foreach my $addiauthfield (@addiauthfields) {
713 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
714 foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
715 REALmodaddauthor( $dbh, $biblionumber,
716 $addiauthsubfields[$subfieldcount] );
719 ( $tagfield, $tagsubfield ) =
720 MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
721 my @subtitlefields = $record->field($tagfield);
722 foreach my $subtitlefield (@subtitlefields) {
723 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
724 foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
725 REALnewsubtitle( $dbh, $biblionumber,
726 $subtitlesubfields[$subfieldcount] );
729 ( $tagfield, $tagsubfield ) =
730 MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
731 my @subj = $record->field($tagfield);
733 foreach my $subject (@subj) {
734 my @subjsubfield = $subject->subfield($tagsubfield);
735 foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
736 push @subjects, $subjsubfield[$subfieldcount];
739 REALmodsubject( $dbh, $biblionumber, 1, @subjects );
740 return ( $biblionumber, $biblioitemnumber );
743 =head2 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
747 modify the framework of a biblio
753 sub NEWmodbiblioframework {
754 my ($dbh,$biblionumber,$frameworkcode) =@_;
755 my $sth = $dbh->prepare("Update biblio SET frameworkcode=? WHERE biblionumber=?");
756 $sth->execute($frameworkcode,$biblionumber);
760 =head2 NEWmodbiblio($dbh,$MARCrecord,$biblionumber,$frameworkcode);
764 modify a biblio (MARC=ON)
771 my ($dbh,$record,$biblionumber,$frameworkcode) =@_;
772 $frameworkcode="" unless $frameworkcode;
773 # &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
774 my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
776 $oldbiblio->{frameworkcode} = $frameworkcode;
777 #create the marc entry, that stores the rax marc record in Koha 3.0
778 $oldbiblio->{marc} = $record->as_usmarc();
779 $oldbiblio->{marcxml} = $record->as_xml();
781 REALmodbiblio($dbh,$oldbiblio);
782 REALmodbiblitem($dbh,$oldbiblio);
783 # now, modify addi authors, subject, addititles.
784 my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
785 my @addiauthfields = $record->field($tagfield);
786 foreach my $addiauthfield (@addiauthfields) {
787 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
788 foreach my $subfieldcount (0..$#addiauthsubfields) {
789 REALmodaddauthor($dbh,$biblionumber,$addiauthsubfields[$subfieldcount]);
792 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
793 my @subtitlefields = $record->field($tagfield);
794 foreach my $subtitlefield (@subtitlefields) {
795 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
796 # delete & create subtitle again because REALmodsubtitle can't handle new subtitles
798 $dbh->do("delete from bibliosubtitle where biblionumber=$biblionumber");
799 foreach my $subfieldcount (0..$#subtitlesubfields) {
800 foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
801 REALnewsubtitle($dbh,$biblionumber,$subtit);
805 ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
806 my @subj = $record->field($tagfield);
808 foreach my $subject (@subj) {
809 my @subjsubfield = $subject->subfield($tagsubfield);
810 foreach my $subfieldcount (0..$#subjsubfield) {
811 push @subjects,$subjsubfield[$subfieldcount];
814 REALmodsubject($dbh,$biblionumber,1,@subjects);
818 =head2 NEWmodbilbioframework($dbh,$biblionumber,$frameworkcode);
829 my ( $dbh, $bibid ) = @_;
830 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
831 &REALdelbiblio( $dbh, $biblio );
834 "select biblioitemnumber from biblioitems where biblionumber=?");
835 $sth->execute($biblio);
836 while ( my ($biblioitemnumber) = $sth->fetchrow ) {
837 REALdelbiblioitem( $dbh, $biblioitemnumber );
839 &MARCdelbiblio( $dbh, $bibid, 0 );
842 =head2 $itemnumber = NEWnewitem($dbh, $record, $biblionumber, $biblioitemnumber);
846 creates an item from a MARC::Record
853 my ( $dbh, $record, $biblionumber, $biblioitemnumber ) = @_;
856 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
857 my $item = &MARCmarc2koha( $dbh, $record,$frameworkcode );
858 # needs old biblionumber and biblioitemnumber
859 $item->{'biblionumber'} = $biblionumber;
860 $item->{'biblioitemnumber'}=$biblioitemnumber;
861 $item->{marc} = $record->as_usmarc();
862 my ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, $item->{barcode} );
867 =head2 $itemnumber = NEWmoditem($dbh, $record, $biblionumber, $biblioitemnumber,$itemnumber);
878 my ( $dbh, $record, $biblionumber, $biblioitemnumber, $itemnumber) = @_;
880 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber);
881 my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
883 $olditem->{marc} = $record->as_usmarc();
884 $olditem->{biblionumber} = $biblionumber;
885 $olditem->{biblioitemnumber} = $biblioitemnumber;
887 REALmoditem( $dbh, $olditem );
891 =head2 $itemnumber = NEWdelitem($dbh, $biblionumber, $biblioitemnumber, $itemnumber);
902 my ( $dbh, $bibid, $itemnumber ) = @_;
903 my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
904 &REALdelitem( $dbh, $itemnumber );
905 &MARCdelitem( $dbh, $bibid, $itemnumber );
909 =head2 $biblionumber = REALnewbiblio($dbh,$biblio);
913 adds a record in biblio table. Datas are in the hash $biblio.
920 my ( $dbh, $biblio ) = @_;
922 $dbh->do('lock tables biblio WRITE');
923 my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
925 my $data = $sth->fetchrow_arrayref;
926 my $bibnum = $$data[0] + 1;
929 if ( $biblio->{'seriestitle'} ) { $series = 1 }
932 $dbh->prepare("insert into biblio set biblionumber=?, title=?, author=?, copyrightdate=?,
933 serial=?, seriestitle=?, notes=?, abstract=?,
937 $bibnum, $biblio->{'title'},
938 $biblio->{'author'}, $biblio->{'copyrightdate'},
939 $biblio->{'serial'}, $biblio->{'seriestitle'},
940 $biblio->{'notes'}, $biblio->{'abstract'},
941 $biblio->{'unititle'}
945 $dbh->do('unlock tables');
949 =head2 $biblionumber = REALmodbiblio($dbh,$biblio);
953 modify a record in biblio table. Datas are in the hash $biblio.
960 my ( $dbh, $biblio ) = @_;
961 my $sth = $dbh->prepare("Update biblio set title=?, author=?, abstract=?, copyrightdate=?,
962 seriestitle=?, serial=?, unititle=?, notes=?, frameworkcode=?
963 where biblionumber = ?"
966 $biblio->{'title'}, $biblio->{'author'},
967 $biblio->{'abstract'}, $biblio->{'copyrightdate'},
968 $biblio->{'seriestitle'}, $biblio->{'serial'},
969 $biblio->{'unititle'}, $biblio->{'notes'},
970 $biblio->{frameworkcode},
971 $biblio->{'biblionumber'}
974 return ( $biblio->{'biblionumber'} );
977 =head2 REALmodsubtitle($dbh,$bibnum,$subtitle);
981 modify subtitles in bibliosubtitle table.
987 sub REALmodsubtitle {
988 my ( $dbh, $bibnum, $subtitle ) = @_;
991 "update bibliosubtitle set subtitle = ? where biblionumber = ?");
992 $sth->execute( $subtitle, $bibnum );
996 =head2 REALmodaddauthor($dbh,$bibnum,$author);
1000 adds or modify additional authors
1001 NOTE : Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1007 sub REALmodaddauthor {
1008 my ( $dbh, $bibnum, @authors ) = @_;
1010 # my $dbh = C4Connect;
1012 $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1014 $sth->execute($bibnum);
1016 foreach my $author (@authors) {
1017 if ( $author ne '' ) {
1020 "Insert into additionalauthors set author = ?, biblionumber = ?"
1023 $sth->execute( $author, $bibnum );
1028 } # sub modaddauthor
1030 =head2 $errors = REALmodsubject($dbh,$bibnum, $force, @subject);
1034 modify/adds subjects
1039 sub REALmodsubject {
1040 my ( $dbh, $bibnum, $force, @subject ) = @_;
1042 # my $dbh = C4Connect;
1043 my $count = @subject;
1045 for ( my $i = 0 ; $i < $count ; $i++ ) {
1046 $subject[$i] =~ s/^ //g;
1047 $subject[$i] =~ s/ $//g;
1050 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1052 $sth->execute( $subject[$i] );
1054 if ( my $data = $sth->fetchrow_hashref ) {
1057 if ( $force eq $subject[$i] || $force == 1 ) {
1059 # subject not in aut, chosen to force anway
1060 # so insert into cataloguentry so its in auth file
1063 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1066 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1071 "$subject[$i]\n does not exist in the subject authority file";
1074 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1076 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1078 while ( my $data = $sth2->fetchrow_hashref ) {
1079 $error .= "<br>$data->{'catalogueentry'}";
1086 if ( $error eq '' ) {
1088 $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1089 $sth->execute($bibnum);
1093 "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1095 foreach $query (@subject) {
1096 $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1105 =head2 REALmodbiblitem($dbh, $biblioitem);
1114 sub REALmodbiblitem {
1115 my ( $dbh, $biblioitem ) = @_;
1118 my $sth = $dbh->prepare("update biblioitems set itemtype=?, url=?, isbn=?, issn=?,
1119 publishercode=?, publicationyear=?, classification=?, dewey=?,
1120 subclass=?, illus=?, pages=?, volumeddesc=?,
1121 notes=?, size=?, place=?, marc=?,
1123 where biblioitemnumber=?");
1124 $sth->execute( $biblioitem->{itemtype}, $biblioitem->{url}, $biblioitem->{isbn}, $biblioitem->{issn},
1125 $biblioitem->{publishercode}, $biblioitem->{publicationyear}, $biblioitem->{classification}, $biblioitem->{dewey},
1126 $biblioitem->{subclass}, $biblioitem->{illus}, $biblioitem->{pages}, $biblioitem->{volumeddesc},
1127 $biblioitem->{bnotes}, $biblioitem->{size}, $biblioitem->{place}, $biblioitem->{marc},
1128 $biblioitem->{marcxml}, $biblioitem->{biblioitemnumber});
1129 # warn "MOD : $biblioitem->{biblioitemnumber} = ".$biblioitem->{marc};
1132 =head2 REALnewbiblioitem($dbh,$biblioitem);
1136 adds a biblioitem ($biblioitem is a hash with the values)
1142 sub REALnewbiblioitem {
1143 my ( $dbh, $biblioitem ) = @_;
1145 $dbh->do("lock tables biblioitems WRITE, biblio WRITE");
1146 my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1148 my $biblioitemnumber;
1151 $data = $sth->fetchrow_arrayref;
1152 $biblioitemnumber = $$data[0] + 1;
1154 # Insert biblioitemnumber in MARC record, we need it to manage items later...
1155 my $frameworkcode=MARCfind_frameworkcode($dbh,$biblioitem->{biblionumber});
1156 my ($biblioitemnumberfield,$biblioitemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'biblioitems.biblioitemnumber',$frameworkcode);
1157 my $record = MARC::File::USMARC::decode($biblioitem->{marc});
1158 my $field=$record->field($biblioitemnumberfield);
1159 $field->update($biblioitemnumbersubfield => "$biblioitemnumber");
1160 $biblioitem->{marc} = $record->as_usmarc();
1161 $biblioitem->{marcxml} = $record->as_xml();
1163 $sth = $dbh->prepare( "insert into biblioitems set
1164 biblioitemnumber = ?, biblionumber = ?,
1165 volume = ?, number = ?,
1166 classification = ?, itemtype = ?,
1168 issn = ?, dewey = ?,
1169 subclass = ?, publicationyear = ?,
1170 publishercode = ?, volumedate = ?,
1171 volumeddesc = ?, illus = ?,
1172 pages = ?, notes = ?,
1174 marc = ?, place = ?,
1178 $biblioitemnumber, $biblioitem->{'biblionumber'},
1179 $biblioitem->{'volume'}, $biblioitem->{'number'},
1180 $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1181 $biblioitem->{'url'}, $biblioitem->{'isbn'},
1182 $biblioitem->{'issn'}, $biblioitem->{'dewey'},
1183 $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
1184 $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
1185 $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
1186 $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
1187 $biblioitem->{'size'}, $biblioitem->{'lccn'},
1188 $biblioitem->{'marc'}, $biblioitem->{'place'},
1189 $biblioitem->{marcxml},
1191 $dbh->do("unlock tables");
1192 return ($biblioitemnumber);
1195 =head2 REALnewsubtitle($dbh,$bibnum,$subtitle);
1199 create a new subtitle
1204 sub REALnewsubtitle {
1205 my ( $dbh, $bibnum, $subtitle ) = @_;
1208 "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1209 $sth->execute( $bibnum, $subtitle ) if $subtitle;
1213 =head2 ($itemnumber,$errors)= REALnewitems($dbh,$item,$barcode);
1217 create a item. $item is a hash and $barcode the barcode.
1224 my ( $dbh, $item, $barcode ) = @_;
1226 # warn "OLDNEWITEMS";
1228 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1229 my $sth = $dbh->prepare("Select max(itemnumber) from items");
1234 $data = $sth->fetchrow_hashref;
1235 $itemnumber = $data->{'max(itemnumber)'} + 1;
1237 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1238 if ( $item->{'loan'} ) {
1239 $item->{'notforloan'} = $item->{'loan'};
1242 # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1243 if ( $item->{'dateaccessioned'} ) {
1244 $sth = $dbh->prepare( "Insert into items set
1245 itemnumber = ?, biblionumber = ?,
1246 multivolumepart = ?,
1247 biblioitemnumber = ?, barcode = ?,
1248 booksellerid = ?, dateaccessioned = ?,
1249 homebranch = ?, holdingbranch = ?,
1250 price = ?, replacementprice = ?,
1251 replacementpricedate = NOW(), datelastseen = NOW(),
1252 multivolume = ?, stack = ?,
1253 itemlost = ?, wthdrawn = ?,
1254 paidfor = ?, itemnotes = ?,
1255 itemcallnumber =?, notforloan = ?,
1260 $itemnumber, $item->{'biblionumber'},
1261 $item->{'multivolumepart'},
1262 $item->{'biblioitemnumber'},$barcode,
1263 $item->{'booksellerid'}, $item->{'dateaccessioned'},
1264 $item->{'homebranch'}, $item->{'holdingbranch'},
1265 $item->{'price'}, $item->{'replacementprice'},
1266 $item->{multivolume}, $item->{stack},
1267 $item->{itemlost}, $item->{wthdrawn},
1268 $item->{paidfor}, $item->{'itemnotes'},
1269 $item->{'itemcallnumber'}, $item->{'notforloan'},
1272 if ( defined $sth->errstr ) {
1273 $error .= $sth->errstr;
1277 $sth = $dbh->prepare( "Insert into items set
1278 itemnumber = ?, biblionumber = ?,
1279 multivolumepart = ?,
1280 biblioitemnumber = ?, barcode = ?,
1281 booksellerid = ?, dateaccessioned = NOW(),
1282 homebranch = ?, holdingbranch = ?,
1283 price = ?, replacementprice = ?,
1284 replacementpricedate = NOW(), datelastseen = NOW(),
1285 multivolume = ?, stack = ?,
1286 itemlost = ?, wthdrawn = ?,
1287 paidfor = ?, itemnotes = ?,
1288 itemcallnumber =?, notforloan = ?,
1293 $itemnumber, $item->{'biblionumber'},
1294 $item->{'multivolumepart'},
1295 $item->{'biblioitemnumber'},$barcode,
1296 $item->{'booksellerid'},
1297 $item->{'homebranch'}, $item->{'holdingbranch'},
1298 $item->{'price'}, $item->{'replacementprice'},
1299 $item->{multivolume}, $item->{stack},
1300 $item->{itemlost}, $item->{wthdrawn},
1301 $item->{paidfor}, $item->{'itemnotes'},
1302 $item->{'itemcallnumber'}, $item->{'notforloan'},
1305 if ( defined $sth->errstr ) {
1306 $error .= $sth->errstr;
1309 # item stored, now, deal with the marc part...
1310 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1311 where biblio.biblionumber=biblioitems.biblionumber and
1312 biblio.biblionumber=?");
1313 $sth->execute($item->{biblionumber});
1314 if ( defined $sth->errstr ) {
1315 $error .= $sth->errstr;
1317 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1318 warn "ERROR IN OLDnewitem, MARC record not found FOR $item->{biblionumber} => $rawmarc <=" unless $rawmarc;
1319 my $record = MARC::File::USMARC::decode($rawmarc);
1320 # ok, we have the marc record, add item number to the item field (in {marc}, and add the field to the record)
1321 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1322 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1323 my $itemfield = $itemrecord->field($itemnumberfield);
1324 $itemfield->add_subfields($itemnumbersubfield => "$itemnumber");
1325 $record->insert_grouped_field($itemfield);
1326 # save the record into biblioitem
1327 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=?");
1328 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber});
1329 if ( defined $sth->errstr ) {
1330 $error .= $sth->errstr;
1332 $dbh->do('unlock tables');
1333 return ( $itemnumber, $error );
1336 =head2 REALmoditem($dbh,$item);
1347 my ( $dbh, $item ) = @_;
1349 $dbh->do('lock tables items WRITE, biblio WRITE,biblioitems WRITE');
1350 $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1351 my $query = "update items set barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1353 $item->{'barcode'}, $item->{'notes'},
1354 $item->{'itemcallnumber'}, $item->{'notforloan'},
1355 $item->{'location'}, $item->{multivolumepart},
1356 $item->{multivolume}, $item->{stack},
1359 if ( $item->{'lost'} ne '' ) {
1360 $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1361 itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1362 location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1364 $item->{'bibitemnum'}, $item->{'barcode'},
1365 $item->{'notes'}, $item->{'homebranch'},
1366 $item->{'lost'}, $item->{'wthdrawn'},
1367 $item->{'itemcallnumber'}, $item->{'notforloan'},
1368 $item->{'location'}, $item->{multivolumepart},
1369 $item->{multivolume}, $item->{stack},
1372 if ($item->{homebranch}) {
1373 $query.=",homebranch=?";
1374 push @bind, $item->{homebranch};
1376 if ($item->{holdingbranch}) {
1377 $query.=",holdingbranch=?";
1378 push @bind, $item->{holdingbranch};
1381 $query.=" where itemnumber=?";
1382 push @bind,$item->{'itemnum'};
1383 if ( $item->{'replacement'} ne '' ) {
1384 $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1386 my $sth = $dbh->prepare($query);
1387 $sth->execute(@bind);
1389 # item stored, now, deal with the marc part...
1390 $sth = $dbh->prepare("select biblioitems.marc,biblio.frameworkcode from biblioitems,biblio
1391 where biblio.biblionumber=biblioitems.biblionumber and
1392 biblio.biblionumber=? and
1393 biblioitems.biblioitemnumber=?");
1394 $sth->execute($item->{biblionumber},$item->{biblioitemnumber});
1395 if ( defined $sth->errstr ) {
1396 $error .= $sth->errstr;
1398 my ($rawmarc,$frameworkcode) = $sth->fetchrow;
1399 warn "ERROR IN REALmoditem, MARC record not found" unless $rawmarc;
1400 my $record = MARC::File::USMARC::decode($rawmarc);
1401 # ok, we have the marc record, find the previous item record for this itemnumber and delete it
1402 my ($itemnumberfield,$itemnumbersubfield) = MARCfind_marc_from_kohafield($dbh,'items.itemnumber',$frameworkcode);
1403 # prepare the new item record
1404 my $itemrecord = MARC::File::USMARC::decode($item->{marc});
1405 my $itemfield = $itemrecord->field($itemnumberfield);
1406 $itemfield->add_subfields($itemnumbersubfield => '$itemnumber');
1407 # parse all fields fields from the complete record
1408 foreach ($record->field($itemnumberfield)) {
1409 # when the previous field is found, replace by the new one
1410 if ($_->subfield($itemnumbersubfield) == $item->{itemnum}) {
1411 $_->replace_with($itemfield);
1414 # $record->insert_grouped_field($itemfield);
1415 # save the record into biblioitem
1416 $sth=$dbh->prepare("update biblioitems set marc=?,marcxml=? where biblionumber=? and biblioitemnumber=?");
1417 $sth->execute($record->as_usmarc(),$record->as_xml(),$item->{biblionumber},$item->{biblioitemnumber});
1418 if ( defined $sth->errstr ) {
1419 $error .= $sth->errstr;
1421 $dbh->do('unlock tables');
1426 =head2 REALdelitem($dbh,$itemnum);
1437 my ( $dbh, $itemnum ) = @_;
1439 # my $dbh=C4Connect;
1440 my $sth = $dbh->prepare("select * from items where itemnumber=?");
1441 $sth->execute($itemnum);
1442 my $data = $sth->fetchrow_hashref;
1444 my $query = "Insert into deleteditems set ";
1446 foreach my $temp ( keys %$data ) {
1447 $query .= "$temp = ?,";
1448 push ( @bind, $data->{$temp} );
1453 $sth = $dbh->prepare($query);
1454 $sth->execute(@bind);
1456 $sth = $dbh->prepare("Delete from items where itemnumber=?");
1457 $sth->execute($itemnum);
1463 =head2 REALdelbiblioitem($dbh,$biblioitemnumber);
1467 deletes a biblioitem
1468 NOTE : not standard sub name. Should be REALdelbiblioitem()
1474 sub REALdelbiblioitem {
1475 my ( $dbh, $biblioitemnumber ) = @_;
1477 # my $dbh = C4Connect;
1478 my $sth = $dbh->prepare( "Select * from biblioitems
1479 where biblioitemnumber = ?"
1483 $sth->execute($biblioitemnumber);
1485 if ( $results = $sth->fetchrow_hashref ) {
1489 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1490 isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1491 pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1495 $results->{biblioitemnumber}, $results->{biblionumber},
1496 $results->{volume}, $results->{number},
1497 $results->{classification}, $results->{itemtype},
1498 $results->{isbn}, $results->{issn},
1499 $results->{dewey}, $results->{subclass},
1500 $results->{publicationyear}, $results->{publishercode},
1501 $results->{volumedate}, $results->{volumeddesc},
1502 $results->{timestamp}, $results->{illus},
1503 $results->{pages}, $results->{notes},
1504 $results->{size}, $results->{url},
1508 $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1509 $sth2->execute($biblioitemnumber);
1514 # Now delete all the items attached to the biblioitem
1515 $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1516 $sth->execute($biblioitemnumber);
1518 while ( my $data = $sth->fetchrow_hashref ) {
1519 my $query = "Insert into deleteditems set ";
1521 foreach my $temp ( keys %$data ) {
1522 $query .= "$temp = ?,";
1523 push ( @bind, $data->{$temp} );
1526 my $sth2 = $dbh->prepare($query);
1527 $sth2->execute(@bind);
1530 $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1531 $sth->execute($biblioitemnumber);
1535 } # sub deletebiblioitem
1537 =head2 REALdelbiblio($dbh,$biblio);
1548 my ( $dbh, $biblio ) = @_;
1549 my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1550 $sth->execute($biblio);
1551 if ( my $data = $sth->fetchrow_hashref ) {
1553 my $query = "Insert into deletedbiblio set ";
1555 foreach my $temp ( keys %$data ) {
1556 $query .= "$temp = ?,";
1557 push ( @bind, $data->{$temp} );
1560 #replacing the last , by ",?)"
1562 $sth = $dbh->prepare($query);
1563 $sth->execute(@bind);
1565 $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
1566 $sth->execute($biblio);
1572 =head2 $number = itemcount($biblio);
1576 returns the number of items attached to a biblio
1584 my $dbh = C4::Context->dbh;
1587 my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
1588 $sth->execute($biblio);
1589 my $data = $sth->fetchrow_hashref;
1591 return ( $data->{'count(*)'} );
1594 =head2 $biblionumber = newbiblio($biblio);
1598 create a biblio. The parameter is a hash
1606 my $dbh = C4::Context->dbh;
1607 my $bibnum = REALnewbiblio( $dbh, $biblio );
1608 # finds new (MARC bibid
1609 # my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1610 my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
1611 MARCaddbiblio( $dbh, $record, $bibnum,'' );
1615 =head2 $biblionumber = &modbiblio($biblio);
1619 Update a biblio record.
1621 C<$biblio> is a reference-to-hash whose keys are the fields in the
1622 biblio table in the Koha database. All fields must be present, not
1623 just the ones you wish to change.
1625 C<&modbiblio> updates the record defined by
1626 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
1628 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
1637 my $dbh = C4::Context->dbh;
1638 my $biblionumber=REALmodbiblio($dbh,$biblio);
1639 my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
1640 # finds new (MARC bibid
1641 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
1642 MARCmodbiblio($dbh,$bibid,$record,"",0);
1643 return($biblionumber);
1646 =head2 &modsubtitle($biblionumber, $subtitle);
1650 Sets the subtitle of a book.
1652 C<$biblionumber> is the biblionumber of the book to modify.
1654 C<$subtitle> is the new subtitle.
1661 my ( $bibnum, $subtitle ) = @_;
1662 my $dbh = C4::Context->dbh;
1663 &REALmodsubtitle( $dbh, $bibnum, $subtitle );
1666 =head2 &modaddauthor($biblionumber, $author);
1670 Replaces all additional authors for the book with biblio number
1671 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
1672 C<&modaddauthor> deletes all additional authors.
1679 my ( $bibnum, @authors ) = @_;
1680 my $dbh = C4::Context->dbh;
1681 &REALmodaddauthor( $dbh, $bibnum, @authors );
1682 } # sub modaddauthor
1684 =head2 $error = &modsubject($biblionumber, $force, @subjects);
1688 $force - a subject to force
1689 $error - Error message, or undef if successful.
1696 my ( $bibnum, $force, @subject ) = @_;
1697 my $dbh = C4::Context->dbh;
1698 my $error = &REALmodsubject( $dbh, $bibnum, $force, @subject );
1700 # When MARC is off, ensures that the MARC biblio table gets updated with new
1701 # subjects, of course, it deletes the biblio in marc, and then recreates.
1702 # This check is to ensure that no MARC data exists to lose.
1703 if (C4::Context->preference("MARC") eq '0'){
1704 my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
1705 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
1706 &MARCmodbiblio($dbh,$bibid, $MARCRecord);
1712 =head2 modbibitem($biblioitem);
1716 modify a biblioitem. The parameter is a hash
1723 my ($biblioitem) = @_;
1724 my $dbh = C4::Context->dbh;
1725 &REALmodbiblitem( $dbh, $biblioitem );
1728 =head2 $biblioitemnumber = newbiblioitem($biblioitem)
1732 create a biblioitem, the parameter is a hash
1739 my ($biblioitem) = @_;
1740 my $dbh = C4::Context->dbh;
1741 my $bibitemnum = &REALnewbiblioitem( $dbh, $biblioitem );
1744 MARCkoha2marcBiblio( $dbh, 0, $bibitemnum )
1745 ; # the 0 means "do NOT retrieve biblio, only biblioitem, in the MARC record
1747 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh,
1748 $biblioitem->{biblionumber} );
1749 &MARCaddbiblio( $dbh, $MARCbiblio, $biblioitem->{biblionumber}, '',$bibid );
1750 return ($bibitemnum);
1753 =head2 newsubtitle($biblionumber,$subtitle);
1757 insert a subtitle for $biblionumber biblio
1765 my ( $bibnum, $subtitle ) = @_;
1766 my $dbh = C4::Context->dbh;
1767 &REALnewsubtitle( $dbh, $bibnum, $subtitle );
1770 =head2 $errors = newitems($item, @barcodes);
1774 insert items ($item is a hash)
1782 my ( $item, @barcodes ) = @_;
1783 my $dbh = C4::Context->dbh;
1787 foreach my $barcode (@barcodes) {
1788 ( $itemnumber, $error ) = &REALnewitems( $dbh, $item, uc($barcode) );
1791 &MARCkoha2marcItem( $dbh, $item->{biblionumber}, $itemnumber );
1792 &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
1797 =head2 moditem($item);
1801 modify an item ($item is a hash with all item informations)
1810 my $dbh = C4::Context->dbh;
1811 &REALmoditem( $dbh, $item );
1813 &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
1815 &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
1816 &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
1819 =head2 $error = checkitems($count,@barcodes);
1823 check for each @barcode entry that the barcode is not a duplicate
1830 my ( $count, @barcodes ) = @_;
1831 my $dbh = C4::Context->dbh;
1833 my $sth = $dbh->prepare("Select * from items where barcode=?");
1834 for ( my $i = 0 ; $i < $count ; $i++ ) {
1835 $barcodes[$i] = uc $barcodes[$i];
1836 $sth->execute( $barcodes[$i] );
1837 if ( my $data = $sth->fetchrow_hashref ) {
1838 $error .= " Duplicate Barcode: $barcodes[$i]";
1845 =head2 $delitem($itemnum);
1849 delete item $itemnum being the item number to delete
1857 my $dbh = C4::Context->dbh;
1858 &REALdelitem( $dbh, $itemnum );
1861 =head2 deletebiblioitem($biblioitemnumber);
1865 delete the biblioitem $biblioitemnumber
1871 sub deletebiblioitem {
1872 my ($biblioitemnumber) = @_;
1873 my $dbh = C4::Context->dbh;
1874 &REALdelbiblioitem( $dbh, $biblioitemnumber );
1875 } # sub deletebiblioitem
1877 =head2 delbiblio($biblionumber)
1881 delete biblio $biblionumber
1889 my $dbh = C4::Context->dbh;
1890 &REALdelbiblio( $dbh, $biblio );
1891 my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
1892 &MARCdelbiblio( $dbh, $bibid, 0 );
1895 =head2 ($count,@results) = getbiblio($biblionumber);
1899 return an array with hash of biblios.
1901 FIXME : biblionumber being the primary key, this sub will always return only 1 result, API should be modified...
1908 my ($biblionumber) = @_;
1909 my $dbh = C4::Context->dbh;
1910 my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
1912 # || die "Cannot prepare $query\n" . $dbh->errstr;
1916 $sth->execute($biblionumber);
1918 # || die "Cannot execute $query\n" . $sth->errstr;
1919 while ( my $data = $sth->fetchrow_hashref ) {
1920 $results[$count] = $data;
1925 return ( $count, @results );
1928 =head2 ($count,@results) = getbiblioitem($biblioitemnumber);
1932 return an array with hash of biblioitemss.
1934 FIXME : biblioitemnumber being unique, this sub will always return only 1 result, API should be modified...
1941 my ($biblioitemnum) = @_;
1942 my $dbh = C4::Context->dbh;
1943 my $sth = $dbh->prepare( "Select * from biblioitems where
1944 biblioitemnumber = ?"
1949 $sth->execute($biblioitemnum);
1951 while ( my $data = $sth->fetchrow_hashref ) {
1952 $results[$count] = $data;
1957 return ( $count, @results );
1958 } # sub getbiblioitem
1960 =head2 ($count,@results) = getbiblioitembybiblionumber($biblionumber);
1964 return an array with hash of biblioitems for the given biblionumber.
1970 sub getbiblioitembybiblionumber {
1971 my ($biblionumber) = @_;
1972 my $dbh = C4::Context->dbh;
1973 my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
1977 $sth->execute($biblionumber);
1979 while ( my $data = $sth->fetchrow_hashref ) {
1980 $results[$count] = $data;
1985 return ( $count, @results );
1988 =head2 ($count,@results) = getitemsbybiblioitem($biblionumber);
1992 returns an array with hash of items
1998 sub getitemsbybiblioitem {
1999 my ($biblioitemnum) = @_;
2000 my $dbh = C4::Context->dbh;
2001 my $sth = $dbh->prepare( "Select * from items, biblio where
2002 biblio.biblionumber = items.biblionumber and biblioitemnumber
2006 # || die "Cannot prepare $query\n" . $dbh->errstr;
2010 $sth->execute($biblioitemnum);
2012 # || die "Cannot execute $query\n" . $sth->errstr;
2013 while ( my $data = $sth->fetchrow_hashref ) {
2014 $results[$count] = $data;
2019 return ( $count, @results );
2020 } # sub getitemsbybiblioitem
2024 # converts ISO 5426 coded string to ISO 8859-1
2025 # sloppy code : should be improved in next issue
2026 my ( $string, $encoding ) = @_;
2029 # $encoding = C4::Context->preference("marcflavour") unless $encoding;
2030 if ( $encoding eq "UNIMARC" ) {
2099 # this handles non-sorting blocks (if implementation requires this)
2100 $string = nsb_clean($_);
2102 elsif ( $encoding eq "USMARC" || $encoding eq "MARC21" ) {
2103 if (/[\xc1-\xff]/) {
2156 # this handles non-sorting blocks (if implementation requires this)
2157 $string = nsb_clean($_);
2164 my $NSB = '\x88'; # NSB : begin Non Sorting Block
2165 my $NSE = '\x89'; # NSE : Non Sorting Block end
2166 # handles non sorting blocks
2170 s/[ ]{0,1}$NSE/) /gm;
2177 my $dbh = C4::Context->dbh;
2178 my $result = MARCmarc2koha($dbh,$record,'');
2180 my ($biblionumber,$bibid,$title);
2181 # search duplicate on ISBN, easy and fast...
2182 if ($result->{isbn}) {
2183 $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=?");
2184 $sth->execute($result->{'isbn'});
2185 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2186 return $biblionumber,$bibid,$title if ($biblionumber);
2188 # a more complex search : build a request for SearchMarc::catalogsearch()
2189 my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2190 # search on biblio.title
2191 my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2192 if ($record->field($tag)) {
2193 if ($record->field($tag)->subfields($subfield)) {
2194 push @tags, "'".$tag.$subfield."'";
2195 push @and_or, "and";
2196 push @excluding, "";
2197 push @operator, "contains";
2198 push @value, $record->field($tag)->subfield($subfield);
2199 # warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2202 # ... and on biblio.author
2203 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2204 if ($record->field($tag)) {
2205 if ($record->field($tag)->subfields($subfield)) {
2206 push @tags, "'".$tag.$subfield."'";
2207 push @and_or, "and";
2208 push @excluding, "";
2209 push @operator, "contains";
2210 push @value, $record->field($tag)->subfield($subfield);
2211 # warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2214 # ... and on publicationyear.
2215 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2216 if ($record->field($tag)) {
2217 if ($record->field($tag)->subfields($subfield)) {
2218 push @tags, "'".$tag.$subfield."'";
2219 push @and_or, "and";
2220 push @excluding, "";
2221 push @operator, "=";
2222 push @value, $record->field($tag)->subfield($subfield);
2223 # warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2227 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2228 if ($record->field($tag)) {
2229 if ($record->field($tag)->subfields($subfield)) {
2230 push @tags, "'".$tag.$subfield."'";
2231 push @and_or, "and";
2232 push @excluding, "";
2233 push @operator, "=";
2234 push @value, $record->field($tag)->subfield($subfield);
2235 # warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2238 # ... and on publisher.
2239 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2240 if ($record->field($tag)) {
2241 if ($record->field($tag)->subfields($subfield)) {
2242 push @tags, "'".$tag.$subfield."'";
2243 push @and_or, "and";
2244 push @excluding, "";
2245 push @operator, "=";
2246 push @value, $record->field($tag)->subfield($subfield);
2247 # warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2250 # ... and on volume.
2251 ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2252 if ($record->field($tag)) {
2253 if ($record->field($tag)->subfields($subfield)) {
2254 push @tags, "'".$tag.$subfield."'";
2255 push @and_or, "and";
2256 push @excluding, "";
2257 push @operator, "=";
2258 push @value, $record->field($tag)->subfield($subfield);
2259 # warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2263 my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2264 # there is at least 1 result => return the 1st one
2266 # warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2267 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2269 # no result, returns nothing
2276 if(substr($isbn, 0, 1) <=7) {
2277 $seg1 = substr($isbn, 0, 1);
2278 } elsif(substr($isbn, 0, 2) <= 94) {
2279 $seg1 = substr($isbn, 0, 2);
2280 } elsif(substr($isbn, 0, 3) <= 995) {
2281 $seg1 = substr($isbn, 0, 3);
2282 } elsif(substr($isbn, 0, 4) <= 9989) {
2283 $seg1 = substr($isbn, 0, 4);
2285 $seg1 = substr($isbn, 0, 5);
2287 my $x = substr($isbn, length($seg1));
2289 if(substr($x, 0, 2) <= 19) {
2290 # if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2291 $seg2 = substr($x, 0, 2);
2292 } elsif(substr($x, 0, 3) <= 699) {
2293 $seg2 = substr($x, 0, 3);
2294 } elsif(substr($x, 0, 4) <= 8399) {
2295 $seg2 = substr($x, 0, 4);
2296 } elsif(substr($x, 0, 5) <= 89999) {
2297 $seg2 = substr($x, 0, 5);
2298 } elsif(substr($x, 0, 6) <= 9499999) {
2299 $seg2 = substr($x, 0, 6);
2301 $seg2 = substr($x, 0, 7);
2303 my $seg3=substr($x,length($seg2));
2304 $seg3=substr($seg3,0,length($seg3)-1) ;
2305 my $seg4 = substr($x, -1, 1);
2306 return "$seg1-$seg2-$seg3-$seg4";
2310 END { } # module clean-up code here (global destructor)
2316 Koha Developement team <info@koha.org>
2318 Paul POULAIN paul.poulain@free.fr
2324 # Revision 1.127 2005/08/11 14:37:32 tipaul
2326 # * removing useless subs
2327 # * removing some subs that are also elsewhere
2328 # * 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)
2330 # Revision 1.126 2005/08/11 09:13:28 tipaul
2331 # just removing useless subs (a lot !!!) for code cleaning
2333 # Revision 1.125 2005/08/11 09:00:07 tipaul
2334 # Ok guys, this time, it seems that item add and modif begin working as expected...
2335 # Still a lot of bugs to fix, of course
2337 # Revision 1.124 2005/08/10 10:21:15 tipaul
2338 # continuing the road to zebra :
2339 # - the biblio add begins to work.
2340 # - the biblio modif begins to work.
2342 # (still without doing anything on zebra)
2343 # (no new change in updatedatabase)
2345 # Revision 1.123 2005/08/09 14:10:28 tipaul
2346 # 1st commit to go to zebra.
2347 # don't update your cvs if you want to have a working head...
2349 # this commit contains :
2350 # * 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...
2351 # * 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.
2352 # * other files : get rid of bibid and use biblionumber instead.
2355 # * does not do anything on zebra yet.
2356 # * if you rename marc_subfield_table, you can't search anymore.
2357 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
2358 # * 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 ;-) )
2360 # 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
2361 # 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.
2363 # tipaul cutted previous commit notes