use MARC::File::XML;
use ZOOM;
use C4::Koha;
-use C4::Date;
+use C4::Dates qw/format_date/;
use C4::Log; # logaction
use C4::ClassSource;
$olddata->{'biblionumber'} = $biblionumber;
($biblioitemnumber,$error) = _koha_add_biblioitem( $dbh, $olddata );
- # we must add bibnum and bibitemnum in MARC::Record...
- # we build the new field with biblionumber and biblioitemnumber
- # we drop the original field
- # we add the new builded field.
- ( my $biblio_tag, my $biblio_subfield ) = GetMarcFromKohaField("biblio.biblionumber",$frameworkcode);
- ( my $biblioitem_tag, my $biblioitem_subfield ) = GetMarcFromKohaField("biblioitems.biblioitemnumber",$frameworkcode);
-
- my $newfield;
-
- # biblionumber & biblioitemnumber are in different fields
- if ( $biblio_tag != $biblioitem_tag ) {
-
- # deal with biblionumber
- if ( $biblio_tag < 10 ) {
- $newfield = MARC::Field->new( $biblio_tag, $biblionumber );
- }
- else {
- $newfield =
- MARC::Field->new( $biblio_tag, '', '',
- "$biblio_subfield" => $biblionumber );
- }
-
- # drop old field and create new one...
- my $old_field = $record->field($biblio_tag);
- $record->delete_field($old_field);
- $record->append_fields($newfield);
-
- # deal with biblioitemnumber
- if ( $biblioitem_tag < 10 ) {
- $newfield = MARC::Field->new( $biblioitem_tag, $biblioitemnumber, );
- }
- else {
- $newfield =
- MARC::Field->new( $biblioitem_tag, '', '',
- "$biblioitem_subfield" => $biblioitemnumber, );
- }
- # drop old field and create new one...
- $old_field = $record->field($biblioitem_tag);
- $record->delete_field($old_field);
- $record->insert_fields_ordered($newfield);
-
-# biblionumber & biblioitemnumber are in the same field (can't be <10 as fields <10 have only 1 value)
- }
- else {
- my $newfield = MARC::Field->new(
- $biblio_tag, '', '',
- "$biblio_subfield" => $biblionumber,
- "$biblioitem_subfield" => $biblioitemnumber
- );
-
- # drop old field and create new one...
- my $old_field = $record->field($biblio_tag);
- $record->delete_field($old_field);
- $record->insert_fields_ordered($newfield);
- }
+ _koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
# now add the record
$biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
( $item->{'biblioitemnumber'}, $itemtype ) = $sth->fetchrow;
$sth =
$dbh->prepare(
- "SELECT notforloan FROM itemtypes WHERE itemtype='$itemtype'");
- $sth->execute();
+ "SELECT notforloan FROM itemtypes WHERE itemtype=?");
+ $sth->execute( C4::Context->preference('item-level_itypes') ? $item->{'itype'} : $itemtype );
my $notforloan = $sth->fetchrow;
##Change the notforloan field if $notforloan found
if ( $notforloan > 0 ) {
$record->append_fields($field);
}
- # adding biblionumber
- my ($tag_biblionumber, $subfield_biblionumber) = GetMarcFromKohaField('biblio.biblionumber',$frameworkcode);
- $record->append_fields(
- MARC::Field->new(
- $tag_biblionumber,'','',$subfield_biblionumber => $biblionumber
- )
- ) unless ($record->subfield($tag_biblionumber,$subfield_biblionumber));
-
+ # update biblionumber and biblioitemnumber in MARC
+ # FIXME - this is assuming a 1 to 1 relationship between
+ # biblios and biblioitems
+ my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
+ $sth->execute($biblionumber);
+ my ($biblioitemnumber) = $sth->fetchrow;
+ $sth->finish();
+ _koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
+
# update the MARC record (that now contains biblio and items) with the new record data
&ModBiblioMarc( $record, $biblionumber, $frameworkcode );
my $oldbiblio = TransformMarcToKoha( $dbh, $record, $frameworkcode );
# modify the other koha tables
- use Data::Dumper;
- warn "OLDBIB:";
- warn Dumper($oldbiblio);
-
- _koha_modify_biblio( $dbh, $oldbiblio );
- _koha_modify_biblioitem( $dbh, $oldbiblio );
+ _koha_modify_biblio( $dbh, $oldbiblio, $frameworkcode );
+ _koha_modify_biblioitem_nonmarc( $dbh, $oldbiblio );
return 1;
}
my $frameworkcode = GetFrameworkCode( $biblionumber );
ModItemInMarc( $record, $biblionumber, $itemnumber, $frameworkcode );
my $olditem = TransformMarcToKoha( $dbh, $record, $frameworkcode,'items');
+ $olditem->{'biblionumber'} = $biblionumber;
+ my $sth = $dbh->prepare("select biblioitemnumber from biblioitems where biblionumber=?");
+ $sth->execute($biblionumber);
+ my ($biblioitemnumber) = $sth->fetchrow;
+ $sth->finish();
+ $olditem->{'biblioitemnumber'} = $biblioitemnumber;
_koha_modify_item( $dbh, $olditem );
return $biblionumber;
}
my ( $biblionumber, $frameworkcode ) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare(
- "UPDATE biblio SET frameworkcode=? WHERE biblionumber=$biblionumber"
+ "UPDATE biblio SET frameworkcode=? WHERE biblionumber=?"
);
- $sth->execute($frameworkcode);
+ $sth->execute($frameworkcode, $biblionumber);
return 1;
}
my $record = GetMarcItem( $biblionumber, $itemnumber );
my ($tagfield, $tagsubfield) = GetMarcFromKohaField( $itemfield,'');
- if ($tagfield && $tagsubfield) {
+ # FIXME - the condition is done this way because GetMarcFromKohaField
+ # returns (0, 0) if it can't field a MARC tag for the kohafield. However,
+ # some fields like items.wthdrawn are mapped to subfield $0, making the
+ # customary test of "if ($tagfield && $tagsubfield)" incorrect.
+ # GetMarcFromKohaField should probably be returning (undef, undef), making
+ # the correct test "if (defined $tagfield && defined $tagsubfield)", but
+ # this would be a large change and consequently deferred for after 3.0.
+ if (not(int($tagfield) == 0 && int($tagsubfield) == 0)) {
my $tag = $record->field($tagfield);
if ($tag) {
# my $tagsubs = $record->field($tagfield)->subfield($tagsubfield);
$tag->update( $tagsubfield => $newvalue );
$record->delete_field($tag);
$record->insert_fields_ordered($tag);
- &ModItemInMarc( $record, $biblionumber, $itemnumber, 0 );
+ my $frameworkcode = GetFrameworkCode( $biblionumber );
+ &ModItemInMarc( $record, $biblionumber, $itemnumber, $frameworkcode );
}
}
}
=over
-&ModItemInMarc( $record, $biblionumber, $itemnumber )
+&ModItemInMarc( $record, $biblionumber, $itemnumber, $frameworkcode )
=back
# - we need to read the biblio if NoZebra is set (to remove it from the indexes
# - if something goes wrong, the biblio may be deleted from Koha but not from zebra
# and we would have no way to remove it (except manually in zebra, but I bet it would be very hard to handle the problem)
- ModZebra($biblionumber, "delete_record", "biblioserver", undef);
-
- # delete biblio from Koha tables and save in deletedbiblio
- $error = &_koha_delete_biblio( $dbh, $biblionumber );
+ ModZebra($biblionumber, "recordDelete", "biblioserver", undef);
# delete biblioitems and items from Koha tables and save in deletedbiblioitems,deleteditems
$sth =
while ( my $biblioitemnumber = $sth->fetchrow ) {
# delete this biblioitem
- $error = &_koha_delete_biblioitems( $dbh, $biblioitemnumber );
+ $error = _koha_delete_biblioitems( $dbh, $biblioitemnumber );
return $error if $error;
}
+
+ # delete biblio from Koha tables and save in deletedbiblio
+ # must do this *after* _koha_delete_biblioitems, otherwise
+ # delete cascade will prevent deletedbiblioitems rows
+ # from being generated by _koha_delete_biblioitems
+ $error = _koha_delete_biblio( $dbh, $biblionumber );
+
&logaction(C4::Context->userenv->{'number'},"CATALOGUING","DELETE",$biblionumber,"")
if C4::Context->preference("CataloguingLog");
return;
sub DelItem {
my ( $dbh, $biblionumber, $itemnumber ) = @_;
- my $dbh = C4::Context->dbh;
# check the item has no current issues
my ( $bibnum ) = @_;
my $dbh = C4::Context->dbh;
- my $query = "
- SELECT * , biblioitems.notes AS bnotes, itemtypes.notforloan as bi_notforloan, biblio.notes
- FROM biblio
+ # my $query = C4::Context->preference('item-level_itypes') ?
+ # " SELECT * , biblioitems.notes AS bnotes, biblio.notes
+ # FROM biblio
+ # LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber
+ # WHERE biblio.biblionumber = ?
+ # AND biblioitems.biblionumber = biblio.biblionumber
+ #";
+
+ my $query = " SELECT * , biblioitems.notes AS bnotes, itemtypes.notforloan as bi_notforloan, biblio.notes
+ FROM biblio
LEFT JOIN biblioitems ON biblio.biblionumber = biblioitems.biblionumber
LEFT JOIN itemtypes ON biblioitems.itemtype = itemtypes.itemtype
- WHERE biblio.biblionumber = ?
- AND biblioitems.biblionumber = biblio.biblionumber
- ";
+ WHERE biblio.biblionumber = ?
+ AND biblioitems.biblionumber = biblio.biblionumber ";
+
my $sth = $dbh->prepare($query);
$sth->execute($bibnum);
my $data;
my $query = "SELECT *,items.notforloan as itemnotforloan
FROM items
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
- LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
- LEFT JOIN itemtypes on biblioitems.itemtype = itemtypes.itemtype
- WHERE items.biblionumber = ?
- ORDER BY items.dateaccessioned desc
- ";
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber";
+ $query .= (C4::Context->preference('item-level_itypes')) ?
+ " LEFT JOIN itemtypes on items.itype = itemtypes.itemtype "
+ : " LEFT JOIN itemtypes on biblioitems.itemtype = itemtypes.itemtype ";
+ $query .= "WHERE items.biblionumber = ? ORDER BY items.dateaccessioned desc" ;
my $sth = $dbh->prepare($query);
$sth->execute($biblionumber);
my $i = 0;
my @results;
my ( $date_due, $count_reserves );
+ my $isth = $dbh->prepare(
+ "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname,borrowers.branchcode as bcode
+ FROM issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
+ WHERE itemnumber = ?
+ AND returndate IS NULL"
+ );
while ( my $data = $sth->fetchrow_hashref ) {
my $datedue = '';
- my $isth = $dbh->prepare(
- "SELECT issues.*,borrowers.cardnumber,borrowers.surname,borrowers.firstname
- FROM issues LEFT JOIN borrowers ON issues.borrowernumber=borrowers.borrowernumber
- WHERE itemnumber = ?
- AND returndate IS NULL"
- );
$isth->execute( $data->{'itemnumber'} );
if ( my $idata = $isth->fetchrow_hashref ) {
$data->{borrowernumber} = $idata->{borrowernumber};
$data->{surname} = $idata->{surname};
$data->{firstname} = $idata->{firstname};
$datedue = format_date( $idata->{'date_due'} );
+ if (C4::Context->preference("IndependantBranches")){
+ my $userenv = C4::Context->userenv;
+ if ( ($userenv) && ( $userenv->{flags} != 1 ) ) {
+ $data->{'NOTSAMEBRANCH'} = 1 if ($idata->{'bcode'} ne $userenv->{branch});
+ }
+ }
}
if ( $datedue eq '' ) {
#$datedue="Available";
my ( $restype, $reserves ) =
C4::Reserves::CheckReserves( $data->{'itemnumber'} );
if ($restype) {
-
#$datedue=$restype;
$count_reserves = $restype;
}
sub GetBiblioItemData {
my ($biblioitemnumber) = @_;
my $dbh = C4::Context->dbh;
- my $sth =
- $dbh->prepare(
- "SELECT *,biblioitems.notes AS bnotes
- FROM biblioitems,biblio,itemtypes
- WHERE biblio.biblionumber = biblioitems.biblionumber
- AND biblioitemnumber = ? "
- );
+ my $query = "SELECT *,biblioitems.notes AS bnotes
+ FROM biblio, biblioitems ";
+ unless(C4::Context->preference('item-level_itypes')) {
+ $query .= "LEFT JOIN itemtypes on biblioitems.itemtype=itemtypes.itemtype ";
+ }
+ $query .= " WHERE biblio.biblionumber = biblioitems.biblionumber
+ AND biblioitemnumber = ? ";
+ my $sth = $dbh->prepare($query);
my $data;
$sth->execute($biblioitemnumber);
$data = $sth->fetchrow_hashref;
=over 4
-$item = &GetBiblioFromItemNumber($itemnumber);
+$item = &GetBiblioFromItemNumber($itemnumber,$barcode);
-Looks up the item with the given itemnumber.
+Looks up the item with the given itemnumber. if undef, try the barcode.
C<&itemnodata> returns a reference-to-hash whose keys are the fields
from the C<biblio>, C<biblioitems>, and C<items> tables in the Koha
#'
sub GetBiblioFromItemNumber {
- my ( $itemnumber ) = @_;
+ my ( $itemnumber, $barcode ) = @_;
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare(
- "SELECT * FROM items
- LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
- LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
- WHERE items.itemnumber = ?"
- );
-
- $sth->execute($itemnumber);
+ my $sth;
+ if($itemnumber) {
+ $sth=$dbh->prepare( "SELECT * FROM items
+ LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
+ WHERE items.itemnumber = ?") ;
+ $sth->execute($itemnumber);
+ } else {
+ $sth=$dbh->prepare( "SELECT * FROM items
+ LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
+ LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
+ WHERE items.barcode = ?") ;
+ $sth->execute($barcode);
+ }
my $data = $sth->fetchrow_hashref;
$sth->finish;
return ($data);
$marcxml =~ s/\x0c//g;
# warn $marcxml;
my $record = MARC::Record->new();
-
- $record = eval {MARC::Record::new_from_xml( $marcxml, "utf8",C4::Context->preference('marcflavour'))} if ($marcxml);
- if ($@) {warn $@;}
+ if ($marcxml) {
+ $record = eval {MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour'))};
+ if ($@) {warn $@;}
# $record = MARC::Record::new_from_usmarc( $marc) if $marc;
- return $record;
+ return $record;
+ } else {
+ return undef;
+ }
}
=head2 GetXmlBiblio
sub GetMarcItem {
my ( $biblionumber, $itemnumber ) = @_;
- my $dbh = C4::Context->dbh;
- my $newrecord = MARC::Record->new();
- my $marcflavour = C4::Context->preference('marcflavour');
-
- my $marcxml = GetXmlBiblio($biblionumber);
- my $record = MARC::Record->new();
- $record = MARC::Record::new_from_xml( $marcxml, "utf8", $marcflavour );
- # now, find where the itemnumber is stored & extract only the item
- my ( $itemnumberfield, $itemnumbersubfield ) =
- GetMarcFromKohaField( 'items.itemnumber', '' );
- my @fields = $record->field($itemnumberfield);
- foreach my $field (@fields) {
- if ( $field->subfield($itemnumbersubfield) eq $itemnumber ) {
- $newrecord->insert_fields_ordered($field);
- }
- }
- return $newrecord;
+
+ # GetMarcItem has been revised so that it does the following:
+ # 1. Gets the item information from the items table.
+ # 2. Converts it to a MARC field for storage in the bib record.
+ #
+ # The previous behavior was:
+ # 1. Get the bib record.
+ # 2. Return the MARC tag corresponding to the item record.
+ #
+ # The difference is that one treats the items row as authoritative,
+ # while the other treats the MARC representation as authoritative
+ # under certain circumstances.
+ #
+ # FIXME - a big one
+ #
+ # As of 2007-11-27, this change hopefully does not introduce
+ # any bugs. However, it does mean that for code that uses
+ # ModItemInMarconefield to update one subfield (corresponding to
+ # an items column) is now less efficient.
+ #
+ # The API needs to be shifted to the following:
+ # 1. User updates items record.
+ # 2. Linked bib is sent for indexing.
+ #
+ # The missing step 1.5 is updating the item tag in the bib MARC record
+ # so that the indexes are updated. Depending on performance considerations,
+ # this may ultimately mean of of the following:
+ # a. MARC field for item is updated right away.
+ # b. MARC field for item is updated only as part of indexing.
+ # c. MARC field for item is never actually stored in bib record; instead
+ # it is generated only when needed for indexing, item export, and
+ # (maybe) OPAC display.
+ #
+
+ my $itemrecord = GetItem($itemnumber);
+
+ # Tack on 'items.' prefix to column names so that TransformKohaToMarc will work.
+ # Also, don't emit a subfield if the underlying field is blank.
+ my $mungeditem = { map { $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : () } keys %{ $itemrecord } };
+
+ my $itemmarc = TransformKohaToMarc($mungeditem);
+ return $itemmarc;
+
}
$mintag = "600";
$maxtag = "611";
}
+
+ my @marcsubjects;
+ my $subject = "";
+ my $subfield = "";
+ my $marcsubject;
- my @marcsubjcts;
-
- foreach my $field ( $record->fields ) {
+ foreach my $field ( $record->field('6..' )) {
next unless $field->tag() >= $mintag && $field->tag() <= $maxtag;
+ my @subfields_loop;
my @subfields = $field->subfields();
- my $link = "su:";
- my $label;
- my $flag = 0;
- my $authoritysep=C4::Context->preference("authoritysep");
- for my $subject_subfield ( @subfields ) {
- if (
- $marcflavour ne 'MARC21'
- and (
- ($subject_subfield->[0] eq '3') or
- ($subject_subfield->[0] eq '4') or
- ($subject_subfield->[0] eq '5')
- )
- )
- {
- next;
- }
- my $code = $subject_subfield->[0];
- $label .= $subject_subfield->[1].$authoritysep unless ( $code == 9 );
- $link .= " and su-to:".$subject_subfield->[1] unless ( $code == 9 );
- if ( $code == 9 ) {
- $link = "an:".$subject_subfield->[1];
- $flag = 1;
- }
- elsif ( ! $flag ) {
- $link =~ s/ and\ssu-to:$//;
+ my $counter = 0;
+ my @link_loop;
+ # if there is an authority link, build the link with an= subfield9
+ my $subfield9 = $field->subfield('9');
+ for my $subject_subfield (@subfields ) {
+ # don't load unimarc subfields 3,4,5
+ next if (($marcflavour eq "UNIMARC") and ($subject_subfield->[0] =~ (3|4|5) ) );
+ my $code = $subject_subfield->[0];
+ my $value = $subject_subfield->[1];
+ my $linkvalue = $value;
+ $linkvalue =~ s/(\(|\))//g;
+ my $operator = " and " unless $counter==0;
+ if ($subfield9) {
+ @link_loop = ({'limit' => 'an' ,link => "$subfield9" });
+ } else {
+ push @link_loop, {'limit' => 'su', link => $linkvalue, operator => $operator };
}
- }
- $label =~ s/$authoritysep$//;
- push @marcsubjcts,
- {
- label => $label,
- link => $link
- }
- }
- return \@marcsubjcts;
-} #end GetMarcSubjects
+ my $separator = C4::Context->preference("authoritysep") unless $counter==0;
+ # ignore $9
+ push @subfields_loop, {code => $code, value => $value, link_loop => \@link_loop, separator => $separator} unless ($subject_subfield->[0] == 9 );
+ # this needs to be added back in in a way that the template can expose it properly
+ #if ( $code == 9 ) {
+ # $link = "an:".$subject_subfield->[1];
+ # $flag = 1;
+ #}
+ $counter++;
+ }
+
+ push @marcsubjects, { MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop };
+
+ }
+ return \@marcsubjects;
+} #end getMARCsubjects
=head2 GetMarcAuthors
$maxtag = "720";
}
elsif ( $marcflavour eq "UNIMARC" ) { # assume unimarc if not marc21
- $mintag = "701";
+ $mintag = "700";
$maxtag = "712";
}
else {
sub TransformMarcToKoha {
my ( $dbh, $record, $frameworkcode, $table ) = @_;
- my $result;
- # sometimes we only want to return the items data
- if ($table eq 'items') {
- my $sth = $dbh->prepare("SHOW COLUMNS FROM items");
- $sth->execute();
- while ( (my $field) = $sth->fetchrow ) {
- $result = &TransformMarcToKohaOneField( "items", $field, $record, $result, $frameworkcode );
- }
- return $result;
- }
+ my $result;
- my $sth2 = $dbh->prepare("SHOW COLUMNS FROM biblio");
- $sth2->execute();
- my $field;
- while ( ($field) = $sth2->fetchrow ) {
- $result = &TransformMarcToKohaOneField( "biblio", $field, $record, $result, $frameworkcode );
- }
- my $sth2 = $dbh->prepare("SHOW COLUMNS FROM biblioitems");
- $sth2->execute();
- while ( ($field) = $sth2->fetchrow ) {
- if ( $field eq 'notes' ) { $field = 'bnotes'; }
- $result = &TransformMarcToKohaOneField( "biblioitems", $field, $record, $result, $frameworkcode );
- }
- $sth2 = $dbh->prepare("SHOW COLUMNS FROM items");
- $sth2->execute();
- while ( ($field) = $sth2->fetchrow ) {
- $result = &TransformMarcToKohaOneField( "items", $field, $record, $result, $frameworkcode );
+ # sometimes we only want to return the items data
+ if ($table eq 'items') {
+ my $sth = $dbh->prepare("SHOW COLUMNS FROM items");
+ $sth->execute();
+ while ( (my $field) = $sth->fetchrow ) {
+ my $value = get_koha_field_from_marc($table,$field,$record,$frameworkcode);
+ my $key = _disambiguate($table, $field);
+ if ($result->{$key}) {
+ $result->{$key} .= " | " . $value;
+ } else {
+ $result->{$key} = $value;
+ }
+ }
+ return $result;
+ } else {
+ my @tables = ('biblio','biblioitems','items');
+ foreach my $table (@tables){
+ my $sth2 = $dbh->prepare("SHOW COLUMNS from $table");
+ $sth2->execute;
+ while (my ($field) = $sth2->fetchrow){
+ # FIXME use of _disambiguate is a temporary hack
+ # $result->{_disambiguate($table, $field)} = get_koha_field_from_marc($table,$field,$record,$frameworkcode);
+ my $value = get_koha_field_from_marc($table,$field,$record,$frameworkcode);
+ my $key = _disambiguate($table, $field);
+ if ($result->{$key}) {
+ # FIXME - hack to not bring in duplicates of the same value
+ unless (($key eq "biblionumber" or $key eq "biblioitemnumber") and ($value eq "")) {
+ $result->{$key} .= " | " . $value;
+ }
+ } else {
+ $result->{$key} = $value;
+ }
+ }
+ $sth2->finish();
+ }
+ # modify copyrightdate to keep only the 1st year found
+ my $temp = $result->{'copyrightdate'};
+ $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
+ if ( $1 > 0 ) {
+ $result->{'copyrightdate'} = $1;
+ }
+ else { # if no cYYYY, get the 1st date.
+ $temp =~ m/(\d\d\d\d)/;
+ $result->{'copyrightdate'} = $1;
+ }
+
+ # modify publicationyear to keep only the 1st year found
+ $temp = $result->{'publicationyear'};
+ $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
+ if ( $1 > 0 ) {
+ $result->{'publicationyear'} = $1;
+ }
+ else { # if no cYYYY, get the 1st date.
+ $temp =~ m/(\d\d\d\d)/;
+ $result->{'publicationyear'} = $1;
+ }
+ return $result;
}
+}
- # modify copyrightdate to keep only the 1st year found
- my $temp = $result->{'copyrightdate'};
- $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
- if ( $1 > 0 ) {
- $result->{'copyrightdate'} = $1;
- }
- else { # if no cYYYY, get the 1st date.
- $temp =~ m/(\d\d\d\d)/;
- $result->{'copyrightdate'} = $1;
- }
- # modify publicationyear to keep only the 1st year found
- $temp = $result->{'publicationyear'};
- $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
- if ( $1 > 0 ) {
- $result->{'publicationyear'} = $1;
- }
- else { # if no cYYYY, get the 1st date.
- $temp =~ m/(\d\d\d\d)/;
- $result->{'publicationyear'} = $1;
+=head2 _disambiguate
+
+=over 4
+
+$newkey = _disambiguate($table, $field);
+
+This is a temporary hack to distinguish between the
+following sets of columns when using TransformMarcToKoha.
+
+items.cn_source & biblioitems.cn_source
+items.cn_sort & biblioitems.cn_sort
+
+Columns that are currently NOT distinguished (FIXME
+due to lack of time to fully test) are:
+
+biblio.notes and biblioitems.notes
+biblionumber
+timestamp
+biblioitemnumber
+
+FIXME - this is necessary because prefixing each column
+name with the table name would require changing lots
+of code and templates, and exposing more of the DB
+structure than is good to the UI templates, particularly
+since biblio and bibloitems may well merge in a future
+version. In the future, it would also be good to
+separate DB access and UI presentation field names
+more.
+
+=back
+
+=cut
+
+sub _disambiguate {
+ my ($table, $column) = @_;
+ if ($column eq "cn_sort" or $column eq "cn_source") {
+ return $table . '.' . $column;
+ } else {
+ return $column;
}
- return $result;
+
}
+=head2 get_koha_field_from_marc
+
+=over 4
+
+$result->{_disambiguate($table, $field)} = get_koha_field_from_marc($table,$field,$record,$frameworkcode);
+
+Internal function to map data from the MARC record to a specific non-MARC field.
+FIXME: this is meant to replace TransformMarcToKohaOneField after more testing.
+
+=back
+
+=cut
+
+sub get_koha_field_from_marc {
+ my ($koha_table,$koha_column,$record,$frameworkcode) = @_;
+ my ( $tagfield, $subfield ) = GetMarcFromKohaField( $koha_table.'.'.$koha_column, $frameworkcode );
+ my $kohafield;
+ foreach my $field ( $record->field($tagfield) ) {
+ if ( $field->tag() < 10 ) {
+ if ( $kohafield ) {
+ $kohafield .= " | " . $field->data();
+ }
+ else {
+ $kohafield = $field->data();
+ }
+ }
+ else {
+ if ( $field->subfields ) {
+ my @subfields = $field->subfields();
+ foreach my $subfieldcount ( 0 .. $#subfields ) {
+ if ( $subfields[$subfieldcount][0] eq $subfield ) {
+ if ( $kohafield ) {
+ $kohafield .=
+ " | " . $subfields[$subfieldcount][1];
+ }
+ else {
+ $kohafield =
+ $subfields[$subfieldcount][1];
+ }
+ }
+ }
+ }
+ }
+ }
+ return $kohafield;
+}
+
+
=head2 TransformMarcToKohaOneField
=over 4
my %indexes;
foreach my $line (split /('|"),/,$index) {
$line =~ /(.*)=>(.*)/;
+warn $line;
my $index = substr($1,1); # get the index, don't forget to remove initial ' or "
my $fields = $2;
- $index =~ s/'|"| //g;
- $fields =~ s/'|"| //g;
+ $index =~ s/'|"|\s//g;
+
+
+ $fields =~ s/'|"|\s//g;
$indexes{$index}=$fields;
}
return %indexes;
return ( $indicator, @result );
}
+=head2 _koha_marc_update_bib_ids
+
+=over 4
+
+_koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
+
+Internal function to add or update biblionumber and biblioitemnumber to
+the MARC XML.
+
+=back
+
+=cut
+
+sub _koha_marc_update_bib_ids {
+ my ($record, $frameworkcode, $biblionumber, $biblioitemnumber) = @_;
+
+ # we must add bibnum and bibitemnum in MARC::Record...
+ # we build the new field with biblionumber and biblioitemnumber
+ # we drop the original field
+ # we add the new builded field.
+ my ($biblio_tag, $biblio_subfield ) = GetMarcFromKohaField("biblio.biblionumber",$frameworkcode);
+ my ($biblioitem_tag, $biblioitem_subfield ) = GetMarcFromKohaField("biblioitems.biblioitemnumber",$frameworkcode);
+
+ if ($biblio_tag != $biblioitem_tag) {
+ # biblionumber & biblioitemnumber are in different fields
+
+ # deal with biblionumber
+ my ($new_field, $old_field);
+ if ($biblio_tag < 10) {
+ $new_field = MARC::Field->new( $biblio_tag, $biblionumber );
+ } else {
+ $new_field =
+ MARC::Field->new( $biblio_tag, '', '',
+ "$biblio_subfield" => $biblionumber );
+ }
+
+ # drop old field and create new one...
+ $old_field = $record->field($biblio_tag);
+ $record->delete_field($old_field);
+ $record->append_fields($new_field);
+
+ # deal with biblioitemnumber
+ if ($biblioitem_tag < 10) {
+ $new_field = MARC::Field->new( $biblioitem_tag, $biblioitemnumber, );
+ } else {
+ $new_field =
+ MARC::Field->new( $biblioitem_tag, '', '',
+ "$biblioitem_subfield" => $biblioitemnumber, );
+ }
+ # drop old field and create new one...
+ $old_field = $record->field($biblioitem_tag);
+ $record->delete_field($old_field);
+ $record->insert_fields_ordered($new_field);
+
+ } else {
+ # biblionumber & biblioitemnumber are in the same field (can't be <10 as fields <10 have only 1 value)
+ my $new_field = MARC::Field->new(
+ $biblio_tag, '', '',
+ "$biblio_subfield" => $biblionumber,
+ "$biblioitem_subfield" => $biblioitemnumber
+ );
+
+ # drop old field and create new one...
+ my $old_field = $record->field($biblio_tag);
+ $record->delete_field($old_field);
+ $record->insert_fields_ordered($new_field);
+ }
+}
+
=head2 _koha_add_biblio
=over 4
my $error;
- # get the next biblionumber
- my $sth = $dbh->prepare("SELECT MAX(biblionumber) FROM biblio");
- $sth->execute();
- my $data = $sth->fetchrow_arrayref();
- my $biblionumber = $$data[0] + 1;
# set the series flag
my $serial = 0;
if ( $biblio->{'seriestitle'} ) { $serial = 1 };
- $sth->finish();
my $query =
"INSERT INTO biblio
- SET biblionumber = ?,
- frameworkcode = ?,
+ SET frameworkcode = ?,
author = ?,
title = ?,
unititle =?,
datecreated=NOW(),
abstract = ?
";
- $sth = $dbh->prepare($query);
+ my $sth = $dbh->prepare($query);
$sth->execute(
- $biblionumber,
$frameworkcode,
$biblio->{'author'},
$biblio->{'title'},
$biblio->{'abstract'}
);
+ my $biblionumber = $dbh->{'mysql_insertid'};
if ( $dbh->errstr ) {
$error.="ERROR in _koha_add_biblio $query".$dbh->errstr;
warn $error;
=over 4
-my ($biblionumber,$error) == _koha_modify_biblio($dbh,$biblio);
+my ($biblionumber,$error) == _koha_modify_biblio($dbh,$biblio,$frameworkcode);
Internal function for updating the biblio table
=cut
sub _koha_modify_biblio {
- my ( $dbh, $biblio ) = @_;
+ my ( $dbh, $biblio, $frameworkcode ) = @_;
my $error;
my $query = "
my $sth = $dbh->prepare($query);
$sth->execute(
- $biblio->{'frameworkcode'},
+ $frameworkcode,
$biblio->{'author'},
$biblio->{'title'},
$biblio->{'unititle'},
return ( $biblio->{'biblionumber'},$error );
}
-=head2 _koha_modify_biblioitem
+=head2 _koha_modify_biblioitem_nonmarc
=over 4
-my ($biblioitemnumber,$error) = _koha_modify_biblioitem( $dbh, $biblioitem );
+my ($biblioitemnumber,$error) = _koha_modify_biblioitem_nonmarc( $dbh, $biblioitem );
+
+Updates biblioitems row except for marc and marcxml, which should be changed
+via ModBiblioMarc
=back
=cut
-sub _koha_modify_biblioitem {
+sub _koha_modify_biblioitem_nonmarc {
my ( $dbh, $biblioitem ) = @_;
my $error;
# re-calculate the cn_sort, it may have changed
- my ($cn_sort) = GetClassSort($biblioitem->{'cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
+ my ($cn_sort) = GetClassSort($biblioitem->{'biblioitems.cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
my $query =
"UPDATE biblioitems
size = ?,
place = ?,
lccn = ?,
- marc = ?,
url = ?,
cn_source = ?,
cn_class = ?,
cn_item = ?,
cn_suffix = ?,
cn_sort = ?,
- totalissues = ?,
- marcxml = ?
+ totalissues = ?
where biblioitemnumber = ?
";
my $sth = $dbh->prepare($query);
$biblioitem->{'size'},
$biblioitem->{'place'},
$biblioitem->{'lccn'},
- $biblioitem->{'marc'},
$biblioitem->{'url'},
- $biblioitem->{'cn_source'},
+ $biblioitem->{'biblioitems.cn_source'},
$biblioitem->{'cn_class'},
$biblioitem->{'cn_item'},
$biblioitem->{'cn_suffix'},
$cn_sort,
$biblioitem->{'totalissues'},
- $biblioitem->{'marcxml'},
$biblioitem->{'biblioitemnumber'}
);
if ( $dbh->errstr ) {
- $error.="ERROR in _koha_modify_biblioitem $query".$dbh->errstr;
+ $error.="ERROR in _koha_modify_biblioitem_nonmarc $query".$dbh->errstr;
warn $error;
}
return ($biblioitem->{'biblioitemnumber'},$error);
sub _koha_add_biblioitem {
my ( $dbh, $biblioitem ) = @_;
my $error;
- my $sth = $dbh->prepare("SELECT MAX(biblioitemnumber) FROM biblioitems");
- $sth->execute();
- my $data = $sth->fetchrow_arrayref;
- my $bibitemnum = $$data[0] + 1;
- $sth->finish();
- my ($cn_sort) = GetClassSort($biblioitem->{'cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
+ my ($cn_sort) = GetClassSort($biblioitem->{'biblioitems.cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
my $query =
"INSERT INTO biblioitems SET
- biblioitemnumber = ?,
biblionumber = ?,
volume = ?,
number = ?,
";
my $sth = $dbh->prepare($query);
$sth->execute(
- $bibitemnum,
$biblioitem->{'biblionumber'},
$biblioitem->{'volume'},
$biblioitem->{'number'},
$biblioitem->{'lccn'},
$biblioitem->{'marc'},
$biblioitem->{'url'},
- $biblioitem->{'cn_source'},
+ $biblioitem->{'biblioitems.cn_source'},
$biblioitem->{'cn_class'},
$biblioitem->{'cn_item'},
$biblioitem->{'cn_suffix'},
$cn_sort,
$biblioitem->{'totalissues'}
);
+ my $bibitemnum = $dbh->{'mysql_insertid'};
if ( $dbh->errstr ) {
$error.="ERROR in _koha_add_biblioitem $query".$dbh->errstr;
warn $error;
my ( $dbh, $item, $barcode ) = @_;
my $error;
- my $sth = $dbh->prepare("SELECT MAX(itemnumber) FROM items");
- $sth->execute();
- my $data = $sth->fetchrow_hashref;
- my $itemnumber = $data->{'MAX(itemnumber)'} + 1;
- $sth->finish;
-
- my ($items_cn_sort) = GetClassSort($item->{'cn_source'}, $item->{'itemcallnumber'}, "");
+ my ($items_cn_sort) = GetClassSort($item->{'items.cn_source'}, $item->{'itemcallnumber'}, "");
# if dateaccessioned is provided, use it. Otherwise, set to NOW()
if ( $item->{'dateaccessioned'} eq '' || !$item->{'dateaccessioned'} ) {
}
my $query =
"INSERT INTO items SET
- itemnumber = ?,
biblionumber = ?,
biblioitemnumber = ?,
barcode = ?,
paidfor = ?,
location = ?,
onloan = ?,
+ issues = ?,
+ renewals = ?,
+ reserves = ?,
cn_source = ?,
cn_sort = ?,
ccode = ?,
+ itype = ?,
materials = ?,
uri = ?
";
my $sth = $dbh->prepare($query);
$sth->execute(
- $itemnumber,
$item->{'biblionumber'},
$item->{'biblioitemnumber'},
$barcode,
$item->{'paidfor'},
$item->{'location'},
$item->{'onloan'},
- $item->{'cn_source'},
+ $item->{'issues'},
+ $item->{'renewals'},
+ $item->{'reserves'},
+ $item->{'items.cn_source'},
$items_cn_sort,
$item->{'ccode'},
+ $item->{'itype'},
$item->{'materials'},
$item->{'uri'},
);
+ my $itemnumber = $dbh->{'mysql_insertid'};
if ( defined $sth->errstr ) {
$error.="ERROR in _koha_new_items $query".$sth->errstr;
}
my ( $dbh, $item ) = @_;
my $error;
- # calculate items_cn_sort
- my ($items_cn_sort) = GetClassSort($item->{'cn_source'}, $item->{'itemcallnumber'}, "");
+ # calculate items.cn_sort
+ $item->{'cn_sort'} = GetClassSort($item->{'items.cn_source'}, $item->{'itemcallnumber'}, "");
my $query = "UPDATE items SET ";
my @bind;
for my $key ( keys %$item ) {
- # special cases first
- if ($key eq 'cn_sort') {
- $query.="cn_sort=?,";
- push @bind, $items_cn_sort;
- }
- # now all the rest
- else {
- $query.="$key=?,";
- push @bind, $item->{$key};
- }
+ $query.="$key=?,";
+ push @bind, $item->{$key};
}
$query =~ s/,$//;
$query .= " WHERE itemnumber=?";