package C4::Biblio;
# Copyright 2000-2002 Katipo Communications
+# Copyright 2010 BibLibre
+# Copyright 2011 Equinox Software, Inc.
#
# This file is part of Koha.
#
use strict;
use warnings;
+use Carp;
# use utf8;
use MARC::Record;
use C4::Charset;
require C4::Heading;
require C4::Serials;
+require C4::Items;
use vars qw($VERSION @ISA @EXPORT);
&GetISBDView
+ &GetMarcControlnumber
&GetMarcNotes
+ &GetMarcISBN
&GetMarcSubjects
&GetMarcBiblio
&GetMarcAuthors
&GetUsedMarcStructure
&GetXmlBiblio
&GetCOinSBiblio
+ &GetMarcPrice
+ &GetMarcQuantity
&GetAuthorisedValueDesc
&GetMarcStructure
&GetMarcFromKohaField
&GetFrameworkCode
- &GetPublisherNameFromIsbn
&TransformKohaToMarc
&CountItemsIssued
my $dbh = C4::Context->dbh;
# transform the data into koha-table style data
+ SetUTF8Flag($record);
my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode );
( $biblionumber, $error ) = _koha_add_biblio( $dbh, $olddata, $frameworkcode );
$olddata->{'biblionumber'} = $biblionumber;
sub ModBiblio {
my ( $record, $biblionumber, $frameworkcode ) = @_;
+ croak "No record" unless $record;
+
if ( C4::Context->preference("CataloguingLog") ) {
my $newrecord = GetMarcBiblio($biblionumber);
logaction( "CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>" . $newrecord->as_formatted );
}
+ # Cleaning up invalid fields must be done early or SetUTF8Flag is liable to
+ # throw an exception which probably won't be handled.
+ foreach my $field ($record->fields()) {
+ if (! $field->is_control_field()) {
+ if (scalar($field->subfields()) == 0 || (scalar($field->subfields()) == 1 && $field->subfield('9'))) {
+ $record->delete_field($field);
+ }
+ }
+ }
+
+ SetUTF8Flag($record);
my $dbh = C4::Context->dbh;
$frameworkcode = "" unless $frameworkcode;
- # get the items before and append them to the biblio before updating the record, atm we just have the biblio
- my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
- my $oldRecord = GetMarcBiblio($biblionumber);
-
- # delete any item fields from incoming record to avoid
- # duplication or incorrect data - use AddItem() or ModItem()
- # to change items
- foreach my $field ( $record->field($itemtag) ) {
- $record->delete_field($field);
- }
-
- # parse each item, and, for an unknown reason, re-encode each subfield
- # if you don't do that, the record will have encoding mixed
- # and the biblio will be re-encoded.
- # strange, I (Paul P.) searched more than 1 day to understand what happends
- # but could only solve the problem this way...
- my @fields = $oldRecord->field($itemtag);
- foreach my $fielditem (@fields) {
- my $field;
- foreach ( $fielditem->subfields() ) {
- if ($field) {
- $field->add_subfields( Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) );
- } else {
- $field = MARC::Field->new( "$itemtag", '', '', Encode::encode( 'utf-8', $_->[0] ) => Encode::encode( 'utf-8', $_->[1] ) );
- }
- }
- $record->append_fields($field);
- }
+ _strip_item_fields($record, $frameworkcode);
# update biblionumber and biblioitemnumber in MARC
# FIXME - this is assuming a 1 to 1 relationship between
return 1;
}
+=head2 _strip_item_fields
+
+ _strip_item_fields($record, $frameworkcode)
+
+Utility routine to remove item tags from a
+MARC bib.
+
+=cut
+
+sub _strip_item_fields {
+ my $record = shift;
+ my $frameworkcode = shift;
+ # get the items before and append them to the biblio before updating the record, atm we just have the biblio
+ my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+
+ # delete any item fields from incoming record to avoid
+ # duplication or incorrect data - use AddItem() or ModItem()
+ # to change items
+ foreach my $field ( $record->field($itemtag) ) {
+ $record->delete_field($field);
+ }
+}
+
=head2 ModBiblioframework
ModBiblioframework($biblionumber,$frameworkcode);
sub GetISBDView {
my ( $biblionumber, $template ) = @_;
- my $record = GetMarcBiblio($biblionumber);
+ my $record = GetMarcBiblio($biblionumber, 1);
+ return undef unless defined $record;
my $itemtype = &GetFrameworkCode($biblionumber);
my ( $holdingbrtagf, $holdingbrtagsubf ) = &GetMarcFromKohaField( "items.holdingbranch", $itemtype );
my $tagslib = &GetMarcStructure( 1, $itemtype );
- my $ISBD = C4::Context->preference('ISBD');
+ my $ISBD = C4::Context->preference('isbd');
my $bloc = $ISBD;
my $res;
my $blocres;
=head2 GetMarcBiblio
- my $record = GetMarcBiblio($biblionumber);
+ my $record = GetMarcBiblio($biblionumber, [$embeditems]);
Returns MARC::Record representing bib identified by
C<$biblionumber>. If no bib exists, returns undef.
-The MARC record contains both biblio & item data.
+C<$embeditems>. If set to true, items data are included.
+The MARC record contains biblio data, and items data if $embeditems is set to true.
=cut
sub GetMarcBiblio {
my $biblionumber = shift;
+ my $embeditems = shift || 0;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
$sth->execute($biblionumber);
if ($marcxml) {
$record = eval { MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour') ) };
if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; }
+ return unless $record;
+
+ C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems);
# $record = MARC::Record::new_from_usmarc( $marc) if $marc;
return $record;
my $isbn = '';
my $issn = '';
my $publisher = '';
-
- if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
- my $fmts6;
- my $fmts7;
- %$fmts6 = (
- 'a' => 'book',
- 'b' => 'manuscript',
- 'c' => 'book',
- 'd' => 'manuscript',
- 'e' => 'map',
- 'f' => 'map',
- 'g' => 'film',
- 'i' => 'audioRecording',
- 'j' => 'audioRecording',
- 'k' => 'artwork',
- 'l' => 'document',
- 'm' => 'computerProgram',
- 'r' => 'document',
-
- );
- %$fmts7 = (
- 'a' => 'journalArticle',
- 's' => 'journal',
- );
-
- $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book';
-
- if ( $genre eq 'book' ) {
+ my $pages = '';
+ my $titletype = 'b';
+
+ # For the purposes of generating COinS metadata, LDR/06-07 can be
+ # considered the same for UNIMARC and MARC21
+ my $fmts6;
+ my $fmts7;
+ %$fmts6 = (
+ 'a' => 'book',
+ 'b' => 'manuscript',
+ 'c' => 'book',
+ 'd' => 'manuscript',
+ 'e' => 'map',
+ 'f' => 'map',
+ 'g' => 'film',
+ 'i' => 'audioRecording',
+ 'j' => 'audioRecording',
+ 'k' => 'artwork',
+ 'l' => 'document',
+ 'm' => 'computerProgram',
+ 'o' => 'document',
+ 'r' => 'document',
+ );
+ %$fmts7 = (
+ 'a' => 'journalArticle',
+ 's' => 'journal',
+ );
+
+ $genre = $fmts6->{$pos6} ? $fmts6->{$pos6} : 'book';
+
+ if ( $genre eq 'book' ) {
$genre = $fmts7->{$pos7} if $fmts7->{$pos7};
- }
+ }
- ##### We must transform mtx to a valable mtx and document type ####
- if ( $genre eq 'book' ) {
+ ##### We must transform mtx to a valable mtx and document type ####
+ if ( $genre eq 'book' ) {
$mtx = 'book';
- } elsif ( $genre eq 'journal' ) {
+ } elsif ( $genre eq 'journal' ) {
$mtx = 'journal';
- } elsif ( $genre eq 'journalArticle' ) {
+ $titletype = 'j';
+ } elsif ( $genre eq 'journalArticle' ) {
$mtx = 'journal';
$genre = 'article';
- } else {
+ $titletype = 'a';
+ } else {
$mtx = 'dc';
- }
+ }
+
+ $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre";
- $genre = ( $mtx eq 'dc' ) ? "&rft.type=$genre" : "&rft.genre=$genre";
+ if ( C4::Context->preference("marcflavour") eq "UNIMARC" ) {
# Setting datas
- $aulast = $record->subfield( '700', 'a' );
- $aufirst = $record->subfield( '700', 'b' );
+ $aulast = $record->subfield( '700', 'a' ) || '';
+ $aufirst = $record->subfield( '700', 'b' ) || '';
$oauthors = "&rft.au=$aufirst $aulast";
# others authors
( $mtx eq 'dc' )
? "&rft.title=" . $record->subfield( '200', 'a' )
: "&rft.title=" . $record->subfield( '200', 'a' ) . "&rft.btitle=" . $record->subfield( '200', 'a' );
- $pubyear = $record->subfield( '210', 'd' );
- $publisher = $record->subfield( '210', 'c' );
- $isbn = $record->subfield( '010', 'a' );
- $issn = $record->subfield( '011', 'a' );
+ $pubyear = $record->subfield( '210', 'd' ) || '';
+ $publisher = $record->subfield( '210', 'c' ) || '';
+ $isbn = $record->subfield( '010', 'a' ) || '';
+ $issn = $record->subfield( '011', 'a' ) || '';
} else {
# MARC21 need some improve
- my $fmts;
- $mtx = 'book';
- $genre = "&rft.genre=book";
# Setting datas
if ( $record->field('100') ) {
$oauthors .= "&rft.au=$au";
}
}
- $title = "&rft.btitle=" . $record->subfield( '245', 'a' );
+ $title = "&rft." . $titletype . "title=" . $record->subfield( '245', 'a' );
$subtitle = $record->subfield( '245', 'b' ) || '';
$title .= $subtitle;
- $pubyear = $record->subfield( '260', 'c' ) || '';
- $publisher = $record->subfield( '260', 'b' ) || '';
- $isbn = $record->subfield( '020', 'a' ) || '';
- $issn = $record->subfield( '022', 'a' ) || '';
+ if ($titletype eq 'a') {
+ $pubyear = substr $record->field('008')->data(), 7, 4;
+ $isbn = $record->subfield( '773', 'z' ) || '';
+ $issn = $record->subfield( '773', 'x' ) || '';
+ if ($mtx eq 'journal') {
+ $title .= "&rft.title=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')));
+ } else {
+ $title .= "&rft.btitle=" . (($record->subfield( '773', 't' ) || $record->subfield( '773', 'a')) || '');
+ }
+ foreach my $rel ($record->subfield( '773', 'g' )) {
+ if ($pages) {
+ $pages .= ', ';
+ }
+ $pages .= $rel;
+ }
+ } else {
+ $pubyear = $record->subfield( '260', 'c' ) || '';
+ $publisher = $record->subfield( '260', 'b' ) || '';
+ $isbn = $record->subfield( '020', 'a' ) || '';
+ $issn = $record->subfield( '022', 'a' ) || '';
+ }
}
my $coins_value =
-"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear";
+"ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A$mtx$genre$title&rft.isbn=$isbn&rft.issn=$issn&rft.aulast=$aulast&rft.aufirst=$aufirst$oauthors&rft.pub=$publisher&rft.date=$pubyear&rft.pages=$pages";
$coins_value =~ s/(\ |&[^a])/\+/g;
+ $coins_value =~ s/\"/\"\;/g;
#<!-- TMPL_VAR NAME="ocoins_format" -->&rft.au=<!-- TMPL_VAR NAME="author" -->&rft.btitle=<!-- TMPL_VAR NAME="title" -->&rft.date=<!-- TMPL_VAR NAME="publicationyear" -->&rft.pages=<!-- TMPL_VAR NAME="pages" -->&rft.isbn=<!-- TMPL_VAR NAME=amazonisbn -->&rft.aucorp=&rft.place=<!-- TMPL_VAR NAME="place" -->&rft.pub=<!-- TMPL_VAR NAME="publishercode" -->&rft.edition=<!-- TMPL_VAR NAME="edition" -->&rft.series=<!-- TMPL_VAR NAME="series" -->&rft.genre="
return $coins_value;
}
+
+=head2 GetMarcPrice
+
+return the prices in accordance with the Marc format.
+=cut
+
+sub GetMarcPrice {
+ my ( $record, $marcflavour ) = @_;
+ my @listtags;
+ my $subfield;
+
+ if ( $marcflavour eq "MARC21" ) {
+ @listtags = ('345', '020');
+ $subfield="c";
+ } elsif ( $marcflavour eq "UNIMARC" ) {
+ @listtags = ('345', '010');
+ $subfield="d";
+ } else {
+ return;
+ }
+
+ for my $field ( $record->field(@listtags) ) {
+ for my $subfield_value ($field->subfield($subfield)){
+ #check value
+ return $subfield_value if ($subfield_value);
+ }
+ }
+ return 0; # no price found
+}
+
+=head2 GetMarcQuantity
+
+return the quantity of a book. Used in acquisition only, when importing a file an iso2709 from a bookseller
+Warning : this is not really in the marc standard. In Unimarc, Electre (the most widely used bookseller) use the 969$a
+
+=cut
+
+sub GetMarcQuantity {
+ my ( $record, $marcflavour ) = @_;
+ my @listtags;
+ my $subfield;
+
+ if ( $marcflavour eq "MARC21" ) {
+ return 0
+ } elsif ( $marcflavour eq "UNIMARC" ) {
+ @listtags = ('969');
+ $subfield="a";
+ } else {
+ return;
+ }
+
+ for my $field ( $record->field(@listtags) ) {
+ for my $subfield_value ($field->subfield($subfield)){
+ #check value
+ if ($subfield_value) {
+ # in France, the cents separator is the , but sometimes, ppl use a .
+ # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation
+ $subfield_value =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR";
+ return $subfield_value;
+ }
+ }
+ }
+ return 0; # no price found
+}
+
+
=head2 GetAuthorisedValueDesc
my $subfieldvalue =get_authorised_value_desc(
}
}
+=head2 GetMarcControlnumber
+
+ $marccontrolnumber = GetMarcControlnumber($record,$marcflavour);
+
+Get the control number / record Identifier from the MARC record and return it.
+
+=cut
+
+sub GetMarcControlnumber {
+ my ( $record, $marcflavour ) = @_;
+ my $controlnumber = "";
+ # Control number or Record identifier are the same field in MARC21 and UNIMARC
+ # Keep $marcflavour for possible later use
+ if ($marcflavour eq "MARC21" || $marcflavour eq "UNIMARC") {
+ my $controlnumberField = $record->field('001');
+ if ($controlnumberField) {
+ $controlnumber = $controlnumberField->data();
+ }
+ }
+ return $controlnumber;
+}
+
+=head2 GetMarcISBN
+
+ $marcisbnsarray = GetMarcISBN( $record, $marcflavour );
+
+Get all ISBNs from the MARC record and returns them in an array.
+ISBNs stored in differents places depending on MARC flavour
+
+=cut
+
+sub GetMarcISBN {
+ my ( $record, $marcflavour ) = @_;
+ my $scope;
+ if ( $marcflavour eq "UNIMARC" ) {
+ $scope = '010';
+ } else { # assume marc21 if not unimarc
+ $scope = '020';
+ }
+ my @marcisbns;
+ my $isbn = "";
+ my $tag = "";
+ my $marcisbn;
+ foreach my $field ( $record->field($scope) ) {
+ my $value = $field->as_string();
+ if ( $isbn ne "" ) {
+ $marcisbn = { marcisbn => $isbn, };
+ push @marcisbns, $marcisbn;
+ $isbn = $value;
+ }
+ if ( $isbn ne $value ) {
+ $isbn = $isbn . " " . $value;
+ }
+ }
+
+ if ($isbn) {
+ $marcisbn = { marcisbn => $isbn };
+ push @marcisbns, $marcisbn; #load last tag into array
+ }
+ return \@marcisbns;
+} # end GetMarcISBN
+
=head2 GetMarcNotes
$marcnotesarray = GetMarcNotes( $record, $marcflavour );
sub GetMarcNotes {
my ( $record, $marcflavour ) = @_;
my $scope;
- if ( $marcflavour eq "MARC21" ) {
- $scope = '5..';
- } else { # assume unimarc if not marc21
+ if ( $marcflavour eq "UNIMARC" ) {
$scope = '3..';
+ } else { # assume marc21 if not unimarc
+ $scope = '5..';
}
my @marcnotes;
my $note = "";
sub GetMarcSubjects {
my ( $record, $marcflavour ) = @_;
my ( $mintag, $maxtag );
- if ( $marcflavour eq "MARC21" ) {
- $mintag = "600";
- $maxtag = "699";
- } else { # assume unimarc if not marc21
+ if ( $marcflavour eq "UNIMARC" ) {
$mintag = "600";
$maxtag = "611";
+ } else { # assume marc21 if not unimarc
+ $mintag = "600";
+ $maxtag = "699";
}
my @marcsubjects;
my $subfield = "";
my $marcsubject;
+ my $subject_limit = C4::Context->preference("TraceCompleteSubfields") ? 'su,complete-subfield' : 'su';
+
foreach my $field ( $record->field('6..') ) {
next unless $field->tag() >= $mintag && $field->tag() <= $maxtag;
my @subfields_loop;
my $value = $subject_subfield->[1];
my $linkvalue = $value;
$linkvalue =~ s/(\(|\))//g;
- my $operator = " and " unless $counter == 0;
+ my $operator;
+ if ( $counter != 0 ) {
+ $operator = ' and ';
+ }
if ( $code eq 9 ) {
$found9 = 1;
@link_loop = ( { 'limit' => 'an', link => "$linkvalue" } );
}
if ( not $found9 ) {
- push @link_loop, { 'limit' => 'su', link => $linkvalue, operator => $operator };
+ push @link_loop, { 'limit' => $subject_limit, link => $linkvalue, operator => $operator };
+ }
+ my $separator;
+ if ( $counter != 0 ) {
+ $separator = C4::Context->preference('authoritysep');
}
- my $separator = C4::Context->preference("authoritysep") unless $counter == 0;
# ignore $9
my @this_link_loop = @link_loop;
# tagslib useful for UNIMARC author reponsabilities
my $tagslib =
&GetMarcStructure( 1, '' ); # FIXME : we don't have the framework available, we take the default framework. May be buggy on some setups, will be usually correct.
- if ( $marcflavour eq "MARC21" ) {
- $mintag = "700";
- $maxtag = "720";
- } elsif ( $marcflavour eq "UNIMARC" ) { # assume unimarc if not marc21
+ if ( $marcflavour eq "UNIMARC" ) {
$mintag = "700";
$maxtag = "712";
+ } elsif ( $marcflavour eq "MARC21" || $marcflavour eq "NORMARC" ) { # assume marc21 or normarc if not unimarc
+ $mintag = "700";
+ $maxtag = "720";
} else {
return;
}
my $value = $authors_subfield->[1];
my $linkvalue = $value;
$linkvalue =~ s/(\(|\))//g;
- my $operator = " and " unless $count_auth == 0;
+ my $operator;
+ if ( $count_auth != 0 ) {
+ $operator = ' and ';
+ }
# if we have an authority link, use that as the link, otherwise use standard searching
if ($subfield9) {
$value = GetAuthorisedValueDesc( $field->tag(), $authors_subfield->[0], $authors_subfield->[1], '', $tagslib )
if ( $marcflavour eq 'UNIMARC' and ( $authors_subfield->[0] =~ /4/ ) );
my @this_link_loop = @link_loop;
- my $separator = C4::Context->preference("authoritysep") unless $count_auth == 0;
- push @subfields_loop, { code => $subfieldcode, value => $value, link_loop => \@this_link_loop, separator => $separator } unless ( $authors_subfield->[0] eq '9' );
+ my $separator;
+ if ( $count_auth != 0 ) {
+ $separator = C4::Context->preference('authoritysep');
+ }
+ push @subfields_loop,
+ { code => $subfieldcode,
+ value => $value,
+ link_loop => \@this_link_loop,
+ separator => $separator
+ }
+ unless ( $authors_subfield->[0] eq '9' );
$count_auth++;
}
push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop };
sub GetMarcSeries {
my ( $record, $marcflavour ) = @_;
my ( $mintag, $maxtag );
- if ( $marcflavour eq "MARC21" ) {
- $mintag = "440";
- $maxtag = "490";
- } else { # assume unimarc if not marc21
+ if ( $marcflavour eq "UNIMARC" ) {
$mintag = "600";
$maxtag = "619";
+ } else { # assume marc21 if not unimarc
+ $mintag = "440";
+ $maxtag = "490";
}
my @marcseries;
my $value = $series_subfield->[1];
my $linkvalue = $value;
$linkvalue =~ s/(\(|\))//g;
- my $operator = " and " unless $counter == 0;
- push @link_loop, { link => $linkvalue, operator => $operator };
- my $separator = C4::Context->preference("authoritysep") unless $counter == 0;
+ if ( $counter != 0 ) {
+ push @link_loop, { link => $linkvalue, operator => ' and ', };
+ } else {
+ push @link_loop, { link => $linkvalue, operator => undef, };
+ }
+ my $separator;
+ if ( $counter != 0 ) {
+ $separator = C4::Context->preference('authoritysep');
+ }
if ($volume_number) {
push @subfields_loop, { volumenum => $value };
} else {
- push @subfields_loop, { code => $code, value => $value, link_loop => \@link_loop, separator => $separator, volumenum => $volume_number };
+ if ( $series_subfield->[0] ne '9' ) {
+ push @subfields_loop, {
+ code => $code,
+ value => $value,
+ link_loop => \@link_loop,
+ separator => $separator,
+ volumenum => $volume_number,
+ };
+ }
}
$counter++;
}
return $frameworkcode;
}
-=head2 GetPublisherNameFromIsbn
-
- $name = GetPublishercodeFromIsbn($isbn);
- if(defined $name){
- ...
- }
-
-=cut
-
-sub GetPublisherNameFromIsbn($) {
- my $isbn = shift;
- $isbn =~ s/[- _]//g;
- $isbn =~ s/^0*//;
- my @codes = ( split '-', DisplayISBN($isbn) );
- my $code = $codes[0] . $codes[1] . $codes[2];
- my $dbh = C4::Context->dbh;
- my $query = qq{
- SELECT distinct publishercode
- FROM biblioitems
- WHERE isbn LIKE ?
- AND publishercode IS NOT NULL
- LIMIT 1
- };
- my $sth = $dbh->prepare($query);
- $sth->execute("$code%");
- my $name = $sth->fetchrow;
- return $name if length $name;
- return undef;
-}
-
=head2 TransformKohaToMarc
$record = TransformKohaToMarc( $hash )
}
$sth->execute( $frameworkcode, $kohafieldname );
if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
+ my @values = split(/\s?\|\s?/, $value, -1);
+
+ foreach my $itemvalue (@values){
my $tag = $record->field($tagfield);
if ($tag) {
- $tag->update( $tagsubfield => $value );
+ $tag->add_subfields( $tagsubfield => $itemvalue );
$record->delete_field($tag);
$record->insert_fields_ordered($tag);
- } else {
- $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
+ }
+ else {
+ $record->add_fields( $tagfield, " ", " ", $tagsubfield => $itemvalue );
+ }
}
}
return $record;
if ( $tag < 10 ) { # no code for theses fields
# in MARC editor, 000 contains the leader.
if ( $tag eq '000' ) {
- $record->leader( $cgi->param( $params->[ $j + 1 ] ) ) if length( $cgi->param( $params->[ $j + 1 ] ) ) == 24;
-
+ # Force a fake leader even if not provided to avoid crashing
+ # during decoding MARC record containing UTF-8 characters
+ $record->leader(
+ length( $cgi->param($params->[$j+1]) ) == 24
+ ? $cgi->param( $params->[ $j + 1 ] )
+ : ' nam a22 4500'
+ )
+ ;
# between 001 and 009 (included)
} elsif ( $cgi->param( $params->[ $j + 1 ] ) ne '' ) {
$newfield = MARC::Field->new( $tag, $cgi->param( $params->[ $j + 1 ] ), );
my $tagslib = &GetMarcStructure( 1, $frameworkcode );
# return nothing if we don't have found an existing framework.
- return "" unless $tagslib;
- my $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum ) if ($itemnum);
+ return q{} unless $tagslib;
+ my $itemrecord;
+ if ($itemnum) {
+ $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum );
+ }
my @loop_data;
my $authorised_values_sth = $dbh->prepare( "SELECT authorised_value,lib FROM authorised_values WHERE category=? ORDER BY lib" );
foreach my $tag ( sort keys %{$tagslib} ) {
&& C4::Context->preference('itemcallnumber') ) {
my $CNtag = substr( C4::Context->preference('itemcallnumber'), 0, 3 );
my $CNsubfield = substr( C4::Context->preference('itemcallnumber'), 3, 1 );
- my $temp = $itemrecord->field($CNtag) if ($itemrecord);
- if ($temp) {
- $defaultvalue = $temp->subfield($CNsubfield);
+ if ($itemrecord) {
+ my $temp = $itemrecord->field($CNtag);
+ if ($temp) {
+ $defaultvalue = $temp->subfield($CNsubfield);
+ }
}
}
if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
&& $defaultvalues
&& $defaultvalues->{'callnumber'} ) {
- my $temp = $itemrecord->field($subfield) if ($itemrecord);
+ my $temp;
+ if ($itemrecord) {
+ $temp = $itemrecord->field($subfield);
+ }
unless ($temp) {
$defaultvalue = $defaultvalues->{'callnumber'} if $defaultvalues;
}
if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' )
&& $defaultvalues
&& $defaultvalues->{'branchcode'} ) {
- my $temp = $itemrecord->field($subfield) if ($itemrecord);
+ my $temp;
+ if ($itemrecord) {
+ $temp = $itemrecord->field($subfield);
+ }
unless ($temp) {
$defaultvalue = $defaultvalues->{branchcode} if $defaultvalues;
}
}
+ if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.location' )
+ && $defaultvalues
+ && $defaultvalues->{'location'} ) {
+ my $temp = $itemrecord->field($subfield) if ($itemrecord);
+ unless ($temp) {
+ $defaultvalue = $defaultvalues->{location} if $defaultvalues;
+ }
+ }
if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
my @authorised_values;
my %authorised_lib;
-tabindex => '',
-multiple => 0,
);
+ } elsif ( $tagslib->{$tag}->{$subfield}->{value_builder} ) {
+ # opening plugin
+ my $plugin = C4::Context->intranetdir . "/cataloguing/value_builder/" . $tagslib->{$tag}->{$subfield}->{'value_builder'};
+ if (do $plugin) {
+ my $temp;
+ my $extended_param = plugin_parameters( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
+ my ( $function_name, $javascript ) = plugin_javascript( $dbh, $temp, $tagslib, $subfield_data{id}, undef );
+ $subfield_data{random} = int(rand(1000000)); # why do we need 2 different randoms?
+ my $index_subfield = int(rand(1000000));
+ $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".$index_subfield;
+ $subfield_data{marc_value} = qq[<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255"
+ onfocus="Focus$function_name($subfield_data{random}, '$subfield_data{id}');"
+ onblur=" Blur$function_name($subfield_data{random}, '$subfield_data{id}');" />
+ <a href="#" class="buttonDot" onclick="Clic$function_name('$subfield_data{id}'); return false;" title="Tag Editor">...</a>
+ $javascript];
+ } else {
+ warn "Plugin Failed: $plugin";
+ $subfield_data{marc_value} = qq(<input tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" />); # supply default input form
+ }
+ }
+ elsif ( $tag eq '' ) { # it's an hidden field
+ $subfield_data{marc_value} = qq(<input type="hidden" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+ }
+ elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ?
+ $subfield_data{marc_value} = qq(<input type="text" tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255" value="$defaultvalue" />);
+ }
+ elsif ( length($defaultvalue) > 100
+ or (C4::Context->preference("marcflavour") eq "UNIMARC" and
+ 300 <= $tag && $tag < 400 && $subfield eq 'a' )
+ or (C4::Context->preference("marcflavour") eq "MARC21" and
+ 500 <= $tag && $tag < 600 )
+ ) {
+ # oversize field (textarea)
+ $subfield_data{marc_value} = qq(<textarea tabindex="1" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="67" maxlength="255">$defaultvalue</textarea>\n");
} else {
$subfield_data{marc_value} = "<input type=\"text\" name=\"field_value\" value=\"$defaultvalue\" size=\"50\" maxlength=\"255\" />";
}
}
}
}
- my $itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield )
- if ( $itemrecord && $itemrecord->field($itemtagfield) );
+ my $itemnumber;
+ if ( $itemrecord && $itemrecord->field($itemtagfield) ) {
+ $itemnumber = $itemrecord->subfield( $itemtagfield, $itemtagsubfield );
+ }
return {
'itemtagfield' => $itemtagfield,
'itemtagsubfield' => $itemtagsubfield,
return %indexes;
}
+=head2 EmbedItemsInMarcBiblio
+
+ EmbedItemsInMarcBiblio($marc, $biblionumber);
+
+Given a MARC::Record object containing a bib record,
+modify it to include the items attached to it as 9XX
+per the bib's MARC framework.
+
+=cut
+
+sub EmbedItemsInMarcBiblio {
+ my ($marc, $biblionumber) = @_;
+ croak "No MARC record" unless $marc;
+
+ my $frameworkcode = GetFrameworkCode($biblionumber);
+ _strip_item_fields($marc, $frameworkcode);
+
+ # ... and embed the current items
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber = ?");
+ $sth->execute($biblionumber);
+ my @item_fields;
+ my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+ while (my ($itemnumber) = $sth->fetchrow_array) {
+ my $item_marc = C4::Items::GetMarcItem($biblionumber, $itemnumber);
+ push @item_fields, $item_marc->field($itemtag);
+ }
+ $marc->insert_fields_ordered(@item_fields);
+}
+
=head1 INTERNAL FUNCTIONS
=head2 _DelBiblioNoZebra($biblionumber,$record,$server);
# drop old field and create new one...
$old_field = $record->field($biblio_tag);
$record->delete_field($old_field) if $old_field;
- $record->append_fields($new_field);
+ $record->insert_fields_ordered($new_field);
# deal with biblioitemnumber
if ( $biblioitem_tag < 10 ) {
}
substr( $string, 22, 6, "frey50" );
unless ( $record->subfield( 100, "a" ) ) {
- $record->insert_grouped_field( MARC::Field->new( 100, "", "", "a" => $string ) );
+ $record->insert_fields_ordered( MARC::Field->new( 100, "", "", "a" => $string ) );
}
}
+
+ #enhancement 5374: update transaction date (005) for marc21/unimarc
+ if($encoding =~ /MARC21|UNIMARC/) {
+ my @a= (localtime) [5,4,3,2,1,0]; $a[0]+=1900; $a[1]++;
+ # YY MM DD HH MM SS (update year and month)
+ my $f005= $record->field('005');
+ $f005->update(sprintf("%4d%02d%02d%02d%02d%04.1f",@a)) if $f005;
+ }
+
my $oldRecord;
if ( C4::Context->preference("NoZebra") ) {