use MARC::File::XML;
use ZOOM;
use C4::Koha;
-use C4::Date;
+use C4::Branch;
+use C4::Dates qw/format_date/;
use C4::Log; # logaction
use C4::ClassSource;
-
use vars qw($VERSION @ISA @EXPORT);
# TODO: fix version
# EXPORTED FUNCTIONS.
# to add biblios or items
-push @EXPORT, qw( &AddBiblio &AddItem );
+push @EXPORT, qw( &AddBiblio &AddBiblioAndItems );
# to get something
push @EXPORT, qw(
&GetBiblioItemByBiblioNumber
&GetBiblioFromItemNumber
- &GetMarcItem
- &GetItem
&GetItemInfosOf
&GetItemStatus
&GetItemLocation
# To modify something
push @EXPORT, qw(
&ModBiblio
- &ModItem
- &ModItemTransfer
&ModBiblioframework
&ModZebra
- &ModItemInMarc
- &ModItemInMarconefield
- &ModDateLastSeen
);
# To delete something
# but don't use them unless you're a core developer ;-)
push @EXPORT, qw(
&ModBiblioMarc
- &AddItemInMarc
);
# Others functions
sub AddBiblio {
my ( $record, $frameworkcode ) = @_;
- my ($biblionumber,$biblioitemnumber,$error);
+ my ($biblionumber,$biblioitemnumber,$error);
my $dbh = C4::Context->dbh;
# transform the data into koha-table style data
my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode );
$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 );
return ( $biblionumber, $biblioitemnumber );
}
-=head2 AddItem
+=head2 AddBiblioAndItems
+
+=over 4
+
+($biblionumber,$biblioitemnumber, $itemnumber_ref, $error_ref) = AddBiblioAndItems($record, $frameworkcode);
+
+=back
+
+Efficiently add a biblio record and create item records from its
+embedded item fields. This routine is suitable for batch jobs.
+
+The goal of this API is to have a similar effect to using AddBiblio
+and AddItems in succession, but without inefficient repeated
+parsing of the MARC XML bib record.
+
+One functional difference is that the duplicate item barcode
+check is implemented in this API, instead of relying on
+the caller to do it, like AddItem does.
+
+This function returns the biblionumber and biblioitemnumber of the
+new bib, an arrayref of new itemsnumbers, and an arrayref of item
+errors encountered during the processing. Each entry in the errors
+list is a hashref containing the following keys:
=over 2
- $biblionumber = AddItem( $record, $biblionumber)
- Exported function (core API) for adding a new item to Koha
+=item item_sequence
+
+Sequence number of original item tag in the MARC record.
+
+=item item_barcode
+
+Item barcode, provide to assist in the construction of
+useful error messages.
+
+=item error_condition
+
+Code representing the error condition. Can be 'duplicate_barcode',
+'invalid_homebranch', or 'invalid_holdingbranch'.
+
+=item error_information
+
+Additional information appropriate to the error condition.
=back
=cut
-sub AddItem {
- my ( $record, $biblionumber ) = @_;
+sub AddBiblioAndItems {
+ my ( $record, $frameworkcode ) = @_;
+ my ($biblionumber,$biblioitemnumber,$error);
+ my @itemnumbers = ();
+ my @errors = ();
my $dbh = C4::Context->dbh;
+
+ # transform the data into koha-table style data
+ # FIXME - this paragraph copied from AddBiblio
+ my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode );
+ ($biblionumber,$error) = _koha_add_biblio( $dbh, $olddata, $frameworkcode );
+ $olddata->{'biblionumber'} = $biblionumber;
+ ($biblioitemnumber,$error) = _koha_add_biblioitem( $dbh, $olddata );
+
+ # FIXME - this paragraph copied from AddBiblio
+ _koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
+
+ # now we loop through the item tags and start creating items
+ my @bad_item_fields = ();
+ my ($itemtag, $itemsubfield) = &GetMarcFromKohaField("items.itemnumber",'');
+ my $item_sequence_num = 0;
+ ITEMFIELD: foreach my $item_field ($record->field($itemtag)) {
+ $item_sequence_num++;
+ # we take the item field and stick it into a new
+ # MARC record -- this is required so far because (FIXME)
+ # TransformMarcToKoha requires a MARC::Record, not a MARC::Field
+ # and there is no TransformMarcFieldToKoha
+ my $temp_item_marc = MARC::Record->new();
+ $temp_item_marc->append_fields($item_field);
- # add item in old-DB
- my $frameworkcode = GetFrameworkCode( $biblionumber );
- my $item = &TransformMarcToKoha( $dbh, $record, $frameworkcode );
+ # add biblionumber and biblioitemnumber
+ my $item = TransformMarcToKoha( $dbh, $temp_item_marc, $frameworkcode, 'items' );
+ $item->{'biblionumber'} = $biblionumber;
+ $item->{'biblioitemnumber'} = $biblioitemnumber;
+
+ # check for duplicate barcode
+ my %item_errors = CheckItemPreSave($item);
+ if (%item_errors) {
+ push @errors, _repack_item_errors($item_sequence_num, $item, \%item_errors);
+ push @bad_item_fields, $item_field;
+ next ITEMFIELD;
+ }
+ my $duplicate_barcode = exists($item->{'barcode'}) && GetItemnumberFromBarcode($item->{'barcode'});
+ if ($duplicate_barcode) {
+ warn "ERROR: cannot add item $item->{'barcode'} for biblio $biblionumber: duplicate barcode\n";
+ }
- # needs old biblionumber and biblioitemnumber
- $item->{'biblionumber'} = $biblionumber;
- my $sth =
- $dbh->prepare(
- "SELECT biblioitemnumber,itemtype FROM biblioitems WHERE biblionumber=?"
- );
- $sth->execute( $item->{'biblionumber'} );
- my $itemtype;
- ( $item->{'biblioitemnumber'}, $itemtype ) = $sth->fetchrow;
- $sth =
- $dbh->prepare(
- "SELECT notforloan FROM itemtypes WHERE itemtype='$itemtype'");
- $sth->execute();
- my $notforloan = $sth->fetchrow;
- ##Change the notforloan field if $notforloan found
- if ( $notforloan > 0 ) {
- $item->{'notforloan'} = $notforloan;
- &MARCitemchange( $record, "items.notforloan", $notforloan );
+ # Make sure item statuses are set to 0 if empty or NULL in both the item and the MARC
+ for ('notforloan', 'damaged','itemlost','wthdrawn') {
+ if (!$item->{$_} or $item->{$_} eq "") {
+ $item->{$_} = 0;
+ &MARCitemchange( $temp_item_marc, "items.$_", 0 );
+ }
+ }
+
+ # FIXME - dateaccessioned stuff copied from AddItem
+ if ( !$item->{'dateaccessioned'} || $item->{'dateaccessioned'} eq '' ) {
+
+ # find today's date
+ my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
+ localtime(time);
+ $year += 1900;
+ $mon += 1;
+ my $date =
+ "$year-" . sprintf( "%0.2d", $mon ) . "-" . sprintf( "%0.2d", $mday );
+ $item->{'dateaccessioned'} = $date;
+ &MARCitemchange( $temp_item_marc, "items.dateaccessioned", $date );
+ }
+
+ my ( $itemnumber, $error ) = &_koha_new_items( $dbh, $item, $item->{barcode} );
+ warn $error if $error;
+ push @itemnumbers, $itemnumber; # FIXME not checking error
+
+ # FIXME - not copied from AddItem
+ # FIXME - AddItems equiv code about passing $sth to TransformKohaToMarcOneField is stupid
+ &MARCitemchange( $temp_item_marc, "items.itemnumber", $itemnumber );
+
+ &logaction(C4::Context->userenv->{'number'},"CATALOGUING","ADD",$itemnumber,"item")
+ if C4::Context->preference("CataloguingLog");
+
+ $item_field->replace_with($temp_item_marc->field($itemtag));
}
- if ( !$item->{'dateaccessioned'} || $item->{'dateaccessioned'} eq '' ) {
-
- # find today's date
- my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
- localtime(time);
- $year += 1900;
- $mon += 1;
- my $date =
- "$year-" . sprintf( "%0.2d", $mon ) . "-" . sprintf( "%0.2d", $mday );
- $item->{'dateaccessioned'} = $date;
- &MARCitemchange( $record, "items.dateaccessioned", $date );
+
+ # remove any MARC item fields for rejected items
+ foreach my $item_field (@bad_item_fields) {
+ $record->delete_field($item_field);
}
- my ( $itemnumber, $error ) = &_koha_new_items( $dbh, $item, $item->{barcode} );
- # add itemnumber to MARC::Record before adding the item.
- $sth = $dbh->prepare(
-"SELECT tagfield,tagsubfield
-FROM marc_subfield_structure
-WHERE frameworkcode=?
- AND kohafield=?"
- );
- &TransformKohaToMarcOneField( $sth, $record, "items.itemnumber", $itemnumber,
- $frameworkcode );
- # add the item
- &AddItemInMarc( $record, $item->{'biblionumber'},$frameworkcode );
-
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","ADD",$itemnumber,"item")
+ # now add the record
+ # FIXME - this paragraph copied from AddBiblio -- however, moved since
+ # since we need to create the items row and plug in the itemnumbers in the
+ # MARC
+ $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
+
+ # FIXME - when using this API, do we log both bib and item add, or just
+ # bib
+ &logaction(C4::Context->userenv->{'number'},"CATALOGUING","ADD",$biblionumber,"biblio")
if C4::Context->preference("CataloguingLog");
+
+ return ( $biblionumber, $biblioitemnumber, \@itemnumbers, \@errors);
- return ($item->{biblionumber}, $item->{biblioitemnumber},$itemnumber);
+}
+
+sub _repack_item_errors {
+ my $item_sequence_num = shift;
+ my $item_ref = shift;
+ my $error_ref = shift;
+
+ my @repacked_errors = ();
+
+ foreach my $error_code (sort keys %{ $error_ref }) {
+ my $repacked_error = {};
+ $repacked_error->{'item_sequence'} = $item_sequence_num;
+ $repacked_error->{'item_barcode'} = exists($item_ref->{'barcode'}) ? $item_ref->{'barcode'} : '';
+ $repacked_error->{'error_code'} = $error_code;
+ $repacked_error->{'error_information'} = $error_ref->{$error_code};
+ push @repacked_errors, $repacked_error;
+ }
+
+ return @repacked_errors;
}
=head2 ModBiblio
$record->append_fields($field);
}
- # adding biblionumber
- my ($tag_biblionumber, $subfield_biblionumber) = GetMarcFromKohaField('biblio.biblionumber',$frameworkcode);
- if ($tag_biblionumber < 10) {
- $record->append_fields(
- MARC::Field->new(
- $tag_biblionumber, $biblionumber
- )
- ) unless $record->field($tag_biblionumber);
- } else {
- $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;
}
-=head2 ModItem
-
-=over 2
-
-Exported function (core API) for modifying an item in Koha.
-
-=back
-
-=cut
-
-sub ModItem {
- my ( $record, $biblionumber, $itemnumber, $delete, $new_item_hashref )
- = @_;
-
- #logging
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","MODIFY",$itemnumber,$record->as_formatted)
- if C4::Context->preference("CataloguingLog");
-
- my $dbh = C4::Context->dbh;
-
- # if we have a MARC record, we're coming from cataloging and so
- # we do the whole routine: update the MARC and zebra, then update the koha
- # tables
- if ($record) {
- my $frameworkcode = GetFrameworkCode( $biblionumber );
- ModItemInMarc( $record, $biblionumber, $itemnumber, $frameworkcode );
- my $olditem = TransformMarcToKoha( $dbh, $record, $frameworkcode,'items');
- _koha_modify_item( $dbh, $olditem );
- return $biblionumber;
- }
-
- # otherwise, we're just looking to modify something quickly
- # (like a status) so we just update the koha tables
- elsif ($new_item_hashref) {
- _koha_modify_item( $dbh, $new_item_hashref );
- }
-}
-
-sub ModItemTransfer {
- my ( $itemnumber, $frombranch, $tobranch ) = @_;
-
- my $dbh = C4::Context->dbh;
-
- #new entry in branchtransfers....
- my $sth = $dbh->prepare(
- "INSERT INTO branchtransfers (itemnumber, frombranch, datesent, tobranch)
- VALUES (?, ?, NOW(), ?)");
- $sth->execute($itemnumber, $frombranch, $tobranch);
- #update holdingbranch in items .....
- $sth= $dbh->prepare(
- "UPDATE items SET holdingbranch = ? WHERE items.itemnumber = ?");
- $sth->execute($tobranch,$itemnumber);
- &ModDateLastSeen($itemnumber);
- $sth = $dbh->prepare(
- "SELECT biblionumber FROM items WHERE itemnumber=?"
- );
- $sth->execute($itemnumber);
- while ( my ( $biblionumber ) = $sth->fetchrow ) {
- &ModItemInMarconefield( $biblionumber, $itemnumber,
- 'items.holdingbranch', $tobranch );
- }
- return;
-}
-
=head2 ModBiblioframework
ModBiblioframework($biblionumber,$frameworkcode);
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;
}
-=head2 ModItemInMarconefield
-
-=over
-
-modify only 1 field in a MARC item (mainly used for holdingbranch, but could also be used for status modif - moving a book to "lost" on a long overdu for example)
-&ModItemInMarconefield( $biblionumber, $itemnumber, $itemfield, $newvalue )
-
-=back
-
-=cut
-
-sub ModItemInMarconefield {
- my ( $biblionumber, $itemnumber, $itemfield, $newvalue ) = @_;
- my $dbh = C4::Context->dbh;
- if ( !defined $newvalue ) {
- $newvalue = "";
- }
-
- my $record = GetMarcItem( $biblionumber, $itemnumber );
- my ($tagfield, $tagsubfield) = GetMarcFromKohaField( $itemfield,'');
- if ($tagfield && $tagsubfield) {
- 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 );
- }
- }
-}
-
-=head2 ModItemInMarc
-
-=over
-
-&ModItemInMarc( $record, $biblionumber, $itemnumber )
-
-=back
-
-=cut
-
-sub ModItemInMarc {
- my ( $ItemRecord, $biblionumber, $itemnumber, $frameworkcode) = @_;
- my $dbh = C4::Context->dbh;
-
- # get complete MARC record & replace the item field by the new one
- my $completeRecord = GetMarcBiblio($biblionumber);
- my ($itemtag,$itemsubfield) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
- my $itemField = $ItemRecord->field($itemtag);
- my @items = $completeRecord->field($itemtag);
- foreach (@items) {
- if ($_->subfield($itemsubfield) eq $itemnumber) {
-# $completeRecord->delete_field($_);
- $_->replace_with($itemField);
- }
- }
- # save the record
- my $sth = $dbh->prepare("UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
- $sth->execute( $completeRecord->as_usmarc(), $completeRecord->as_xml_record(),$biblionumber );
- $sth->finish;
- ModZebra($biblionumber,"specialUpdate","biblioserver",$completeRecord);
-}
-
-=head2 ModDateLastSeen
-
-&ModDateLastSeen($itemnum)
-Mark item as seen. Is called when an item is issued, returned or manually marked during inventory/stocktaking
-C<$itemnum> is the item number
-
-=cut
-
-sub ModDateLastSeen {
- my ($itemnum) = @_;
- my $dbh = C4::Context->dbh;
- my $sth =
- $dbh->prepare(
- "UPDATE items SET itemlost=0,datelastseen = NOW() WHERE items.itemnumber = ?"
- );
- $sth->execute($itemnum);
- return;
-}
=head2 DelBiblio
=over
my ( $biblionumber ) = @_;
my $dbh = C4::Context->dbh;
my $error; # for error handling
-
- # First make sure this biblio has no items attached
- my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber=?");
- $sth->execute($biblionumber);
- if (my $itemnumber = $sth->fetchrow){
- # Fix this to use a status the template can understand
- $error .= "This Biblio has items attached, please delete them first before deleting this biblio ";
- }
+
+ # First make sure this biblio has no items attached
+ my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber=?");
+ $sth->execute($biblionumber);
+ if (my $itemnumber = $sth->fetchrow){
+ # Fix this to use a status the template can understand
+ $error .= "This Biblio has items attached, please delete them first before deleting this biblio ";
+ }
return $error if $error;
# - 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
-
-
+
+ # check the item has no current issues
+
+
&_koha_delete_item( $dbh, $itemnumber );
# get the MARC record
if C4::Context->preference("CataloguingLog");
}
+=head2 CheckItemPreSave
+
+=over 4
+
+ my $item_ref = TransformMarcToKoha($marc, 'items');
+ # do stuff
+ my %errors = CheckItemPreSave($item_ref);
+ if (exists $errors{'duplicate_barcode'}) {
+ print "item has duplicate barcode: ", $errors{'duplicate_barcode'}, "\n";
+ } elsif (exists $errors{'invalid_homebranch'}) {
+ print "item has invalid home branch: ", $errors{'invalid_homebranch'}, "\n";
+ } elsif (exists $errors{'invalid_holdingbranch'}) {
+ print "item has invalid holding branch: ", $errors{'invalid_holdingbranch'}, "\n";
+ } else {
+ print "item is OK";
+ }
+
+=back
+
+Given a hashref containing item fields, determine if it can be
+inserted or updated in the database. Specifically, checks for
+database integrity issues, and returns a hash containing any
+of the following keys, if applicable.
+
+=over 2
+
+=item duplicate_barcode
+
+Barcode, if it duplicates one already found in the database.
+
+=item invalid_homebranch
+
+Home branch, if not defined in branches table.
+
+=item invalid_holdingbranch
+
+Holding branch, if not defined in branches table.
+
+=back
+
+This function does NOT implement any policy-related checks,
+e.g., whether current operator is allowed to save an
+item that has a given branch code.
+
+=cut
+
+sub CheckItemPreSave {
+ my $item_ref = shift;
+
+ my %errors = ();
+
+ # check for duplicate barcode
+ if (exists $item_ref->{'barcode'} and defined $item_ref->{'barcode'}) {
+ my $existing_itemnumber = GetItemnumberFromBarcode($item_ref->{'barcode'});
+ if ($existing_itemnumber) {
+ if (!exists $item_ref->{'itemnumber'} # new item
+ or $item_ref->{'itemnumber'} != $existing_itemnumber) { # existing item
+ $errors{'duplicate_barcode'} = $item_ref->{'barcode'};
+ }
+ }
+ }
+
+ # check for valid home branch
+ if (exists $item_ref->{'homebranch'} and defined $item_ref->{'homebranch'}) {
+ my $branch_name = GetBranchName($item_ref->{'homebranch'});
+ unless (defined $branch_name) {
+ # relies on fact that branches.branchname is a non-NULL column,
+ # so GetBranchName returns undef only if branch does not exist
+ $errors{'invalid_homebranch'} = $item_ref->{'homebranch'};
+ }
+ }
+
+ # check for valid holding branch
+ if (exists $item_ref->{'holdingbranch'} and defined $item_ref->{'holdingbranch'}) {
+ my $branch_name = GetBranchName($item_ref->{'holdingbranch'});
+ unless (defined $branch_name) {
+ # relies on fact that branches.branchname is a non-NULL column,
+ # so GetBranchName returns undef only if branch does not exist
+ $errors{'invalid_holdingbranch'} = $item_ref->{'holdingbranch'};
+ }
+ }
+
+ return %errors;
+
+}
+
=head2 GetBiblioData
=over 4
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->{cardnumber} = $idata->{cardnumber};
$data->{surname} = $idata->{surname};
$data->{firstname} = $idata->{firstname};
- $datedue = format_date( $idata->{'date_due'} );
+ $datedue = $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;
}
}
if ( my $bdata = $bsth->fetchrow_hashref ) {
$data->{'branchname'} = $bdata->{'branchname'};
}
- my $date = format_date( $data->{'datelastseen'} );
- $data->{'datelastseen'} = $date;
$data->{'datedue'} = $datedue;
$data->{'count_reserves'} = $count_reserves;
my ($lib) = $stackstatus->fetchrow;
$data->{stack} = $lib;
}
+ # Find the last 3 people who borrowed this item.
+ my $sth2 = $dbh->prepare("SELECT * FROM issues,borrowers
+ WHERE itemnumber = ?
+ AND issues.borrowernumber = borrowers.borrowernumber
+ AND returndate IS NOT NULL LIMIT 3");
+ $sth2->execute($data->{'itemnumber'});
+ my $ii = 0;
+ while (my $data2 = $sth2->fetchrow_hashref()) {
+ $data->{"timestamp$ii"} = $data2->{'timestamp'} if $data2->{'timestamp'};
+ $data->{"card$ii"} = $data2->{'cardnumber'} if $data2->{'cardnumber'};
+ $data->{"borrower$ii"} = $data2->{'borrowernumber'} if $data2->{'borrowernumber'};
+ $ii++;
+ }
+
$results[$i] = $data;
$i++;
}
if ( $tag and $subfield ) {
my $sth =
$dbh->prepare(
- "SELECT authorised_value
- FROM marc_subfield_structure
- WHERE tagfield=?
- AND tagsubfield=?
- AND frameworkcode=?
- "
+ "SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE tagfield=?
+ AND tagsubfield=?
+ AND frameworkcode=?
+ "
);
$sth->execute( $tag, $subfield, $fwk );
if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
my $authvalsth =
$dbh->prepare(
- "SELECT authorised_value,lib
- FROM authorised_values
- WHERE category=?
- ORDER BY lib
- "
+ "SELECT authorised_value,lib
+ FROM authorised_values
+ WHERE category=?
+ ORDER BY lib
+ "
);
$authvalsth->execute($authorisedvaluecat);
while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
if ( $tag and $subfield ) {
my $sth =
$dbh->prepare(
- "SELECT authorised_value
- FROM marc_subfield_structure
- WHERE tagfield=?
- AND tagsubfield=?
- AND frameworkcode=?"
+ "SELECT authorised_value
+ FROM marc_subfield_structure
+ WHERE tagfield=?
+ AND tagsubfield=?
+ AND frameworkcode=?"
);
$sth->execute( $tag, $subfield, $fwk );
if ( my ($authorisedvaluecat) = $sth->fetchrow ) {
my $authvalsth =
$dbh->prepare(
- "SELECT authorised_value,lib
- FROM authorised_values
- WHERE category=?
- ORDER BY lib"
+ "SELECT authorised_value,lib
+ FROM authorised_values
+ WHERE category=?
+ ORDER BY lib"
);
$authvalsth->execute($authorisedvaluecat);
while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
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);
return ( $count, @results );
} # sub GetBiblio
-=head2 GetItem
-
-=over 4
-
-$data = &GetItem($itemnumber,$barcode);
-
-return Item information, for a given itemnumber or barcode
-
-=back
-
-=cut
-
-sub GetItem {
- my ($itemnumber,$barcode) = @_;
- my $dbh = C4::Context->dbh;
- if ($itemnumber) {
- my $sth = $dbh->prepare("
- SELECT * FROM items
- WHERE itemnumber = ?");
- $sth->execute($itemnumber);
- my $data = $sth->fetchrow_hashref;
- return $data;
- } else {
- my $sth = $dbh->prepare("
- SELECT * FROM items
- WHERE barcode = ?"
- );
- $sth->execute($barcode);
- my $data = $sth->fetchrow_hashref;
- return $data;
- }
-} # sub GetItem
-
=head2 get_itemnumbers_of
=over 4
=cut
sub GetItemsByBiblioitemnumber {
- my ( $bibitem ) = @_;
- my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ?") || die $dbh->errstr;
- # Get all items attached to a biblioitem
+ my ( $bibitem ) = @_;
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare("SELECT * FROM items WHERE items.biblioitemnumber = ?") || die $dbh->errstr;
+ # Get all items attached to a biblioitem
my $i = 0;
my @results;
$sth->execute($bibitem) || die $sth->errstr;
while ( my $data = $sth->fetchrow_hashref ) {
- # Foreach item, get circulation information
- my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers
+ # Foreach item, get circulation information
+ my $sth2 = $dbh->prepare( "SELECT * FROM issues,borrowers
WHERE itemnumber = ?
AND returndate is NULL
AND issues.borrowernumber = borrowers.borrowernumber"
);
$sth2->execute( $data->{'itemnumber'} );
if ( my $data2 = $sth2->fetchrow_hashref ) {
- # if item is out, set the due date and who it is out too
- $data->{'date_due'} = $data2->{'date_due'};
- $data->{'cardnumber'} = $data2->{'cardnumber'};
- $data->{'borrowernumber'} = $data2->{'borrowernumber'};
- }
+ # if item is out, set the due date and who it is out too
+ $data->{'date_due'} = $data2->{'date_due'};
+ $data->{'cardnumber'} = $data2->{'cardnumber'};
+ $data->{'borrowernumber'} = $data2->{'borrowernumber'};
+ }
else {
- # set date_due to blank, so in the template we check itemlost, and wthdrawn
- $data->{'date_due'} = '';
- } # else
+ # set date_due to blank, so in the template we check itemlost, and wthdrawn
+ $data->{'date_due'} = '';
+ } # else
$sth2->finish;
# Find the last 3 people who borrowed this item.
my $query2 = "SELECT * FROM issues, borrowers WHERE itemnumber = ?
$sth2->execute( $data->{'itemnumber'} ) || die $sth2->errstr;
my $i2 = 0;
while ( my $data2 = $sth2->fetchrow_hashref ) {
- $data->{"timestamp$i2"} = $data2->{'timestamp'};
- $data->{"card$i2"} = $data2->{'cardnumber'};
- $data->{"borrower$i2"} = $data2->{'borrowernumber'};
- $i2++;
- }
+ $data->{"timestamp$i2"} = $data2->{'timestamp'};
+ $data->{"card$i2"} = $data2->{'cardnumber'};
+ $data->{"borrower$i2"} = $data2->{'borrowernumber'};
+ $i2++;
+ }
$sth2->finish;
push(@results,$data);
}
$frameworkcode = "" unless ( $total > 0 );
$sth =
$dbh->prepare(
- "SELECT tagfield,liblibrarian,libopac,mandatory,repeatable
- FROM marc_tag_structure
- WHERE frameworkcode=?
- ORDER BY tagfield"
+ "SELECT tagfield,liblibrarian,libopac,mandatory,repeatable
+ FROM marc_tag_structure
+ WHERE frameworkcode=?
+ ORDER BY tagfield"
);
$sth->execute($frameworkcode);
my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
$sth =
$dbh->prepare(
- "SELECT tagfield,tagsubfield,liblibrarian,libopac,tab,mandatory,repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link,defaultvalue
- FROM marc_subfield_structure
- WHERE frameworkcode=?
- ORDER BY tagfield,tagsubfield
- "
+ "SELECT tagfield,tagsubfield,liblibrarian,libopac,tab,mandatory,repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link,defaultvalue
+ FROM marc_subfield_structure
+ WHERE frameworkcode=?
+ ORDER BY tagfield,tagsubfield
+ "
);
$sth->execute($frameworkcode);
$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
=over 4
my $subfieldvalue =get_authorised_value_desc(
- $tag, $subf[$i][0],$subf[$i][1], '', $taglib);
+ $tag, $subf[$i][0],$subf[$i][1], '', $taglib, $category);
Retrieve the complete description for a given authorised value.
+Now takes $category and $value pair too.
+my $auth_value_desc =GetAuthorisedValueDesc(
+ '','', 'DVD' ,'','','CCODE');
+
=back
=cut
sub GetAuthorisedValueDesc {
- my ( $tag, $subfield, $value, $framework, $tagslib ) = @_;
+ my ( $tag, $subfield, $value, $framework, $tagslib, $category ) = @_;
my $dbh = C4::Context->dbh;
-
- #---- branch
- if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
- return C4::Branch::GetBranchName($value);
- }
- #---- itemtypes
- if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "itemtypes" ) {
- return getitemtypeinfo($value)->{description};
+ if (!$category) {
+#---- branch
+ if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
+ return C4::Branch::GetBranchName($value);
+ }
+
+#---- itemtypes
+ if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "itemtypes" ) {
+ return getitemtypeinfo($value)->{description};
+ }
+
+#---- "true" authorized value
+ $category = $tagslib->{$tag}->{$subfield}->{'authorised_value'}
}
- #---- "true" authorized value
- my $category = $tagslib->{$tag}->{$subfield}->{'authorised_value'};
if ( $category ne "" ) {
my $sth =
- $dbh->prepare(
- "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
- );
+ $dbh->prepare(
+ "SELECT lib FROM authorised_values WHERE category = ? AND authorised_value = ?"
+ );
$sth->execute( $category, $value );
my $data = $sth->fetchrow_hashref;
return $data->{'lib'};
}
}
-=head2 GetMarcItem
-
-=over 4
-
-Returns MARC::Record of the item passed in parameter.
-
-=back
-
-=cut
-
-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;
-}
-
-
-
=head2 GetMarcNotes
=over 4
$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 $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];
- $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 $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 };
}
+ my $separator = C4::Context->preference("authoritysep") unless $counter==0;
+ # ignore $9
+ my @this_link_loop = @link_loop;
+ push @subfields_loop, {code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator} unless ($subject_subfield->[0] == 9 );
+ $counter++;
}
- $label =~ s/$authoritysep$//;
- push @marcsubjcts,
- {
- label => $label,
- link => $link
- }
+
+ push @marcsubjects, { MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop };
+
}
- return \@marcsubjcts;
-} #end GetMarcSubjects
+ return \@marcsubjects;
+} #end getMARCsubjects
=head2 GetMarcAuthors
$maxtag = "720";
}
elsif ( $marcflavour eq "UNIMARC" ) { # assume unimarc if not marc21
- $mintag = "701";
+ $mintag = "700";
$maxtag = "712";
}
- else {
- return;
- }
+ else {
+ return;
+ }
my @marcauthors;
foreach my $field ( $record->fields ) {
next unless $field->tag() >= $mintag && $field->tag() <= $maxtag;
- my %hash;
+ my @subfields_loop;
+ my @link_loop;
my @subfields = $field->subfields();
my $count_auth = 0;
+ # if there is an authority link, build the link with Koha-Auth-Number: subfield9
+ my $subfield9 = $field->subfield('9');
for my $authors_subfield (@subfields) {
- #unimarc-specific line
- next if ($marcflavour eq 'UNIMARC' and (($authors_subfield->[0] eq '3') or ($authors_subfield->[0] eq '5')));
+ # don't load unimarc subfields 3, 5
+ next if ($marcflavour eq 'UNIMARC' and ($authors_subfield->[0] =~ (3|5) ) );
my $subfieldcode = $authors_subfield->[0];
- my $value;
- # deal with UNIMARC author responsibility
- if ( $marcflavour eq 'UNIMARC' and ($authors_subfield->[0] eq '4')) {
- $value = "(".GetAuthorisedValueDesc( $field->tag(), $authors_subfield->[0], $authors_subfield->[1], '', $tagslib ).")";
- } else {
- $value = $authors_subfield->[1];
+ my $value = $authors_subfield->[1];
+ my $linkvalue = $value;
+ $linkvalue =~ s/(\(|\))//g;
+ my $operator = " and " unless $count_auth==0;
+ # if we have an authority link, use that as the link, otherwise use standard searching
+ if ($subfield9) {
+ @link_loop = ({'limit' => 'Koha-Auth-Number' ,link => "$subfield9" });
+ }
+ else {
+ # reset $linkvalue if UNIMARC author responsibility
+ if ( $marcflavour eq 'UNIMARC' and ($authors_subfield->[0] eq '4')) {
+ $linkvalue = "(".GetAuthorisedValueDesc( $field->tag(), $authors_subfield->[0], $authors_subfield->[1], '', $tagslib ).")";
+ }
+ push @link_loop, {'limit' => 'au', link => $linkvalue, operator => $operator };
}
- $hash{tag} = $field->tag;
- $hash{value} .= $value . " " if ($subfieldcode != 9) ;
- $hash{link} .= $value if ($subfieldcode eq 9);
+ 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] == 9 );
+ $count_auth++;
}
- push @marcauthors, \%hash;
+ push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop };
}
return \@marcauthors;
}
}
$marcurl = { MARCURL => $url,
notes => \@notes,
- };
- if($marcflavour eq 'MARC21') {
- my $s3 = $field->subfield('3');
- my $link = $field->subfield('y');
+ };
+ if($marcflavour eq 'MARC21') {
+ my $s3 = $field->subfield('3');
+ my $link = $field->subfield('y');
$marcurl->{'linktext'} = $link || $s3 || $url ;;
$marcurl->{'part'} = $s3 if($link);
$marcurl->{'toc'} = 1 if($s3 =~ /^[Tt]able/) ;
- } else {
- $marcurl->{'linktext'} = $url;
- }
+ } else {
+ $marcurl->{'linktext'} = $url;
+ }
push @marcurls, $marcurl;
- }
+ }
return \@marcurls;
} #end GetMarcUrls
my $counter = 0;
my @link_loop;
for my $series_subfield (@subfields) {
- my $volume_number;
- undef $volume_number;
- # see if this is an instance of a volume
- if ($series_subfield->[0] eq 'v') {
- $volume_number=1;
- }
+ my $volume_number;
+ undef $volume_number;
+ # see if this is an instance of a volume
+ if ($series_subfield->[0] eq 'v') {
+ $volume_number=1;
+ }
my $code = $series_subfield->[0];
my $value = $series_subfield->[1];
my $operator = " and " unless $counter==0;
push @link_loop, {link => $linkvalue, operator => $operator };
my $separator = C4::Context->preference("authoritysep") unless $counter==0;
- if ($volume_number) {
- push @subfields_loop, {volumenum => $value};
- }
- else {
+ 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};
- }
+ }
$counter++;
}
push @marcseries, { MARCSERIES_SUBFIELDS_LOOP => \@subfields_loop };
}
$prevtag = @$tags[$i];
}
- if (C4::Context->preference('marcflavour') and !$unimarc_and_100_exist) {
+ if (C4::Context->preference('marcflavour') eq 'UNIMARC' and !$unimarc_and_100_exist) {
# warn "SETTING 100 for $auth_type";
use POSIX qw(strftime);
my $string = strftime( "%Y%m%d", localtime(time) );
return $record;
}
+# cache inverted MARC field map
+our $inverted_field_map;
+
=head2 TransformMarcToKoha
=over 4
- $result = TransformMarcToKoha( $dbh, $record, $frameworkcode )
+ $result = TransformMarcToKoha( $dbh, $record, $frameworkcode )
=back
-=cut
+Extract data from a MARC bib record into a hashref representing
+Koha biblio, biblioitems, and items fields.
+=cut
sub TransformMarcToKoha {
- my ( $dbh, $record, $frameworkcode, $table ) = @_;
+ my ( $dbh, $record, $frameworkcode, $limit_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 $sth2 = $dbh->prepare("SHOW COLUMNS FROM biblio");
- $sth2->execute();
- my $field;
- while ( ($field) = $sth2->fetchrow ) {
- $result = &TransformMarcToKohaOneField( "biblio", $field, $record, $result, $frameworkcode );
+ unless (defined $inverted_field_map) {
+ $inverted_field_map = _get_inverted_marc_field_map();
}
- 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 );
+
+ my %tables = ();
+ if ($limit_table eq 'items') {
+ $tables{'items'} = 1;
+ } else {
+ $tables{'items'} = 1;
+ $tables{'biblio'} = 1;
+ $tables{'biblioitems'} = 1;
}
- $sth2 = $dbh->prepare("SHOW COLUMNS FROM items");
- $sth2->execute();
- while ( ($field) = $sth2->fetchrow ) {
- $result = &TransformMarcToKohaOneField( "items", $field, $record, $result, $frameworkcode );
+
+ # traverse through record
+ MARCFIELD: foreach my $field ($record->fields()) {
+ my $tag = $field->tag();
+ next MARCFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag};
+ if ($field->is_control_field()) {
+ my $kohafields = $inverted_field_map->{$frameworkcode}->{$tag}->{list};
+ ENTRY: foreach my $entry (@{ $kohafields }) {
+ my ($subfield, $table, $column) = @{ $entry };
+ next ENTRY unless exists $tables{$table};
+ my $key = _disambiguate($table, $column);
+ if ($result->{$key}) {
+ unless (($key eq "biblionumber" or $key eq "biblioitemnumber") and ($field->data() eq "")) {
+ $result->{$key} .= " | " . $field->data();
+ }
+ } else {
+ $result->{$key} = $field->data();
+ }
+ }
+ } else {
+ # deal with subfields
+ MARCSUBFIELD: foreach my $sf ($field->subfields()) {
+ my $code = $sf->[0];
+ next MARCSUBFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code};
+ my $value = $sf->[1];
+ SFENTRY: foreach my $entry (@{ $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code} }) {
+ my ($table, $column) = @{ $entry };
+ next SFENTRY unless exists $tables{$table};
+ my $key = _disambiguate($table, $column);
+ if ($result->{$key}) {
+ unless (($key eq "biblionumber" or $key eq "biblioitemnumber") and ($value eq "")) {
+ $result->{$key} .= " | " . $value;
+ }
+ } else {
+ $result->{$key} = $value;
+ }
+ }
+ }
+ }
}
# 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;
+ if (exists $result->{'copyrightdate'}) {
+ 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;
+ if (exists $result->{'publicationyear'}) {
+ my $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;
}
+sub _get_inverted_marc_field_map {
+ my $relations = C4::Context->marcfromkohafield;
+
+ my $field_map = {};
+ my $relations = C4::Context->marcfromkohafield;
+
+ foreach my $frameworkcode (keys %{ $relations }) {
+ foreach my $kohafield (keys %{ $relations->{$frameworkcode} }) {
+ my $tag = $relations->{$frameworkcode}->{$kohafield}->[0];
+ my $subfield = $relations->{$frameworkcode}->{$kohafield}->[1];
+ my ($table, $column) = split /[.]/, $kohafield, 2;
+ push @{ $field_map->{$frameworkcode}->{$tag}->{list} }, [ $subfield, $table, $column ];
+ push @{ $field_map->{$frameworkcode}->{$tag}->{sfs}->{$subfield} }, [ $table, $column ];
+ }
+ }
+ return $field_map;
+}
+
+=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;
+ }
+
+}
+
+=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 $sth =
$dbh->prepare(
- "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname"
+ "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname"
);
$sth->execute( C4::Context->userenv->{branch} );
push @authorised_values, ""
else {
my $sth =
$dbh->prepare(
- "SELECT branchcode,branchname FROM branches ORDER BY branchname"
+ "SELECT branchcode,branchname FROM branches ORDER BY branchname"
);
$sth->execute;
push @authorised_values, ""
{
my $sth =
$dbh->prepare(
- "SELECT itemtype,description FROM itemtypes ORDER BY description"
+ "SELECT itemtype,description FROM itemtypes ORDER BY description"
);
$sth->execute;
push @authorised_values, ""
}
if ($op eq 'specialUpdate') {
# OK, we have to add or update the record
- # 1st delete (virtually, in indexes) ...
- %result = _DelBiblioNoZebra($biblionumber,$record,$server);
+ # 1st delete (virtually, in indexes), if record actually exists
+ if ($record) {
+ %result = _DelBiblioNoZebra($biblionumber,$record,$server);
+ }
# ... add the record
%result=_AddBiblioNoZebra($biblionumber,$newRecord, $server, %result);
} else {
$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
sub _koha_add_biblio {
my ( $dbh, $biblio, $frameworkcode ) = @_;
- my $error;
+ 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
+ # set the series flag
my $serial = 0;
if ( $biblio->{'seriestitle'} ) { $serial = 1 };
- $sth->finish();
- my $query =
+ my $query =
"INSERT INTO biblio
- SET biblionumber = ?,
- frameworkcode = ?,
- author = ?,
- title = ?,
- unititle =?,
- notes = ?,
- serial = ?,
- seriestitle = ?,
- copyrightdate = ?,
- datecreated=NOW(),
- abstract = ?
- ";
- $sth = $dbh->prepare($query);
+ SET frameworkcode = ?,
+ author = ?,
+ title = ?,
+ unititle =?,
+ notes = ?,
+ serial = ?,
+ seriestitle = ?,
+ copyrightdate = ?,
+ datecreated=NOW(),
+ abstract = ?
+ ";
+ my $sth = $dbh->prepare($query);
$sth->execute(
- $biblionumber,
- $frameworkcode,
+ $frameworkcode,
$biblio->{'author'},
$biblio->{'title'},
- $biblio->{'unititle'},
+ $biblio->{'unititle'},
$biblio->{'notes'},
- $serial,
+ $serial,
$biblio->{'seriestitle'},
- $biblio->{'copyrightdate'},
+ $biblio->{'copyrightdate'},
$biblio->{'abstract'}
);
- if ( $dbh->errstr ) {
- $error.="ERROR in _koha_add_biblio $query".$dbh->errstr;
+ my $biblionumber = $dbh->{'mysql_insertid'};
+ if ( $dbh->errstr ) {
+ $error.="ERROR in _koha_add_biblio $query".$dbh->errstr;
warn $error;
}
$sth->finish();
- #warn "LEAVING _koha_add_biblio: ".$biblionumber."\n";
+ #warn "LEAVING _koha_add_biblio: ".$biblionumber."\n";
return ($biblionumber,$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 $error;
+ my ( $dbh, $biblio, $frameworkcode ) = @_;
+ my $error;
my $query = "
UPDATE biblio
SET frameworkcode = ?,
- author = ?,
- title = ?,
- unititle = ?,
- notes = ?,
- serial = ?,
- seriestitle = ?,
- copyrightdate = ?,
+ author = ?,
+ title = ?,
+ unititle = ?,
+ notes = ?,
+ serial = ?,
+ seriestitle = ?,
+ copyrightdate = ?,
abstract = ?
WHERE biblionumber = ?
- "
- ;
+ "
+ ;
my $sth = $dbh->prepare($query);
$sth->execute(
- $biblio->{'frameworkcode'},
+ $frameworkcode,
$biblio->{'author'},
$biblio->{'title'},
$biblio->{'unititle'},
$biblio->{'serial'},
$biblio->{'seriestitle'},
$biblio->{'copyrightdate'},
- $biblio->{'abstract'},
+ $biblio->{'abstract'},
$biblio->{'biblionumber'}
) if $biblio->{'biblionumber'};
if ( $dbh->errstr || !$biblio->{'biblionumber'} ) {
- $error.="ERROR in _koha_modify_biblio $query".$dbh->errstr;
+ $error.="ERROR in _koha_modify_biblio $query".$dbh->errstr;
warn $error;
}
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;
+ my $error;
- # re-calculate the cn_sort, it may have changed
- my ($cn_sort) = GetClassSort($biblioitem->{'cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
+ # re-calculate the cn_sort, it may have changed
+ my ($cn_sort) = GetClassSort($biblioitem->{'biblioitems.cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
- my $query =
- "UPDATE biblioitems
- SET biblionumber = ?,
- volume = ?,
- number = ?,
+ my $query =
+ "UPDATE biblioitems
+ SET biblionumber = ?,
+ volume = ?,
+ number = ?,
itemtype = ?,
isbn = ?,
issn = ?,
- publicationyear = ?,
+ publicationyear = ?,
publishercode = ?,
- volumedate = ?,
- volumedesc = ?,
- collectiontitle = ?,
- collectionissn = ?,
- collectionvolume= ?,
- editionstatement= ?,
- editionresponsibility = ?,
- illus = ?,
- pages = ?,
- notes = ?,
- size = ?,
- place = ?,
- lccn = ?,
- marc = ?,
- url = ?,
- cn_source = ?,
+ volumedate = ?,
+ volumedesc = ?,
+ collectiontitle = ?,
+ collectionissn = ?,
+ collectionvolume= ?,
+ editionstatement= ?,
+ editionresponsibility = ?,
+ illus = ?,
+ pages = ?,
+ notes = ?,
+ size = ?,
+ place = ?,
+ lccn = ?,
+ url = ?,
+ cn_source = ?,
cn_class = ?,
- cn_item = ?,
- cn_suffix = ?,
- cn_sort = ?,
- totalissues = ?,
- marcxml = ?
+ cn_item = ?,
+ cn_suffix = ?,
+ cn_sort = ?,
+ totalissues = ?
where biblioitemnumber = ?
- ";
- my $sth = $dbh->prepare($query);
- $sth->execute(
- $biblioitem->{'biblionumber'},
- $biblioitem->{'volume'},
- $biblioitem->{'number'},
- $biblioitem->{'itemtype'},
- $biblioitem->{'isbn'},
- $biblioitem->{'issn'},
- $biblioitem->{'publicationyear'},
- $biblioitem->{'publishercode'},
- $biblioitem->{'volumedate'},
- $biblioitem->{'volumedesc'},
- $biblioitem->{'collectiontitle'},
- $biblioitem->{'collectionissn'},
- $biblioitem->{'collectionvolume'},
- $biblioitem->{'editionstatement'},
- $biblioitem->{'editionresponsibility'},
- $biblioitem->{'illus'},
- $biblioitem->{'pages'},
- $biblioitem->{'bnotes'},
- $biblioitem->{'size'},
- $biblioitem->{'place'},
- $biblioitem->{'lccn'},
- $biblioitem->{'marc'},
- $biblioitem->{'url'},
- $biblioitem->{'cn_source'},
- $biblioitem->{'cn_class'},
- $biblioitem->{'cn_item'},
- $biblioitem->{'cn_suffix'},
- $cn_sort,
- $biblioitem->{'totalissues'},
- $biblioitem->{'marcxml'},
- $biblioitem->{'biblioitemnumber'}
- );
+ ";
+ my $sth = $dbh->prepare($query);
+ $sth->execute(
+ $biblioitem->{'biblionumber'},
+ $biblioitem->{'volume'},
+ $biblioitem->{'number'},
+ $biblioitem->{'itemtype'},
+ $biblioitem->{'isbn'},
+ $biblioitem->{'issn'},
+ $biblioitem->{'publicationyear'},
+ $biblioitem->{'publishercode'},
+ $biblioitem->{'volumedate'},
+ $biblioitem->{'volumedesc'},
+ $biblioitem->{'collectiontitle'},
+ $biblioitem->{'collectionissn'},
+ $biblioitem->{'collectionvolume'},
+ $biblioitem->{'editionstatement'},
+ $biblioitem->{'editionresponsibility'},
+ $biblioitem->{'illus'},
+ $biblioitem->{'pages'},
+ $biblioitem->{'bnotes'},
+ $biblioitem->{'size'},
+ $biblioitem->{'place'},
+ $biblioitem->{'lccn'},
+ $biblioitem->{'url'},
+ $biblioitem->{'biblioitems.cn_source'},
+ $biblioitem->{'cn_class'},
+ $biblioitem->{'cn_item'},
+ $biblioitem->{'cn_suffix'},
+ $cn_sort,
+ $biblioitem->{'totalissues'},
+ $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);
+ return ($biblioitem->{'biblioitemnumber'},$error);
}
=head2 _koha_add_biblioitem
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 $error;
- 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 = ?,
cn_sort = ?,
totalissues = ?
";
- my $sth = $dbh->prepare($query);
+ 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;
+ $error.="ERROR in _koha_add_biblioitem $query".$dbh->errstr;
+ warn $error;
}
$sth->finish();
return ($bibitemnum,$error);
sub _koha_new_items {
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 $error;
+ 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 $today = C4::Dates->new();
- $item->{'dateaccessioned'} = $today->output("iso"); #TODO: check time issues
- }
- my $query =
+ my $today = C4::Dates->new();
+ $item->{'dateaccessioned'} = $today->output("iso"); #TODO: check time issues
+ }
+ my $query =
"INSERT INTO items SET
- itemnumber = ?,
- biblionumber = ?,
+ biblionumber = ?,
biblioitemnumber = ?,
- barcode = ?,
- dateaccessioned = ?,
- booksellerid = ?,
+ barcode = ?,
+ dateaccessioned = ?,
+ booksellerid = ?,
homebranch = ?,
price = ?,
- replacementprice = ?,
+ replacementprice = ?,
replacementpricedate = NOW(),
- datelastborrowed = ?,
- datelastseen = NOW(),
- stack = ?,
- notforloan = ?,
- damaged = ?,
- itemlost = ?,
- wthdrawn = ?,
- itemcallnumber = ?,
- restricted = ?,
- itemnotes = ?,
- holdingbranch = ?,
- paidfor = ?,
- location = ?,
- onloan = ?,
- cn_source = ?,
- cn_sort = ?,
- ccode = ?,
- materials = ?,
- uri = ?
+ datelastborrowed = ?,
+ datelastseen = NOW(),
+ stack = ?,
+ notforloan = ?,
+ damaged = ?,
+ itemlost = ?,
+ wthdrawn = ?,
+ itemcallnumber = ?,
+ restricted = ?,
+ itemnotes = ?,
+ holdingbranch = ?,
+ 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'},
+ $sth->execute(
+ $item->{'biblionumber'},
+ $item->{'biblioitemnumber'},
$barcode,
- $item->{'dateaccessioned'},
- $item->{'booksellerid'},
+ $item->{'dateaccessioned'},
+ $item->{'booksellerid'},
$item->{'homebranch'},
$item->{'price'},
- $item->{'replacementprice'},
- $item->{datelastborrowed},
- $item->{stack},
- $item->{'notforloan'},
- $item->{'damaged'},
+ $item->{'replacementprice'},
+ $item->{datelastborrowed},
+ $item->{stack},
+ $item->{'notforloan'},
+ $item->{'damaged'},
$item->{'itemlost'},
- $item->{'wthdrawn'},
- $item->{'itemcallnumber'},
+ $item->{'wthdrawn'},
+ $item->{'itemcallnumber'},
$item->{'restricted'},
- $item->{'itemnotes'},
- $item->{'holdingbranch'},
- $item->{'paidfor'},
- $item->{'location'},
- $item->{'onloan'},
- $item->{'cn_source'},
- $items_cn_sort,
- $item->{'ccode'},
- $item->{'materials'},
- $item->{'uri'},
+ $item->{'itemnotes'},
+ $item->{'holdingbranch'},
+ $item->{'paidfor'},
+ $item->{'location'},
+ $item->{'onloan'},
+ $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;
}
- $sth->finish();
- return ( $itemnumber, $error );
-}
-
-=head2 _koha_modify_item
-
-=over 4
-
-my ($itemnumber,$error) =_koha_modify_item( $dbh, $item, $op );
-
-=back
-
-=cut
-
-sub _koha_modify_item {
- my ( $dbh, $item ) = @_;
- my $error;
-
- # calculate items_cn_sort
- my ($items_cn_sort) = GetClassSort($item->{'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 =~ s/,$//;
- $query .= " WHERE itemnumber=?";
- push @bind, $item->{'itemnumber'};
- my $sth = $dbh->prepare($query);
- $sth->execute(@bind);
- if ( $dbh->errstr ) {
- $error.="ERROR in _koha_modify_item $query".$dbh->errstr;
- warn $error;
- }
$sth->finish();
- return ($item->{'itemnumber'},$error);
+ return ( $itemnumber, $error );
}
=head2 _koha_delete_biblio
sub _koha_delete_item {
my ( $dbh, $itemnum ) = @_;
- # save the deleted item to deleteditems table
+ # save the deleted item to deleteditems table
my $sth = $dbh->prepare("SELECT * FROM items WHERE itemnumber=?");
$sth->execute($itemnum);
my $data = $sth->fetchrow_hashref();
$sth->execute(@bind);
$sth->finish();
- # delete from items table
+ # delete from items table
$sth = $dbh->prepare("DELETE FROM items WHERE itemnumber=?");
$sth->execute($itemnum);
$sth->finish();
- return undef;
+ return undef;
}
=head1 UNEXPORTED FUNCTIONS
return $biblionumber;
}
-=head2 AddItemInMarc
-
-=over 4
-
-$newbiblionumber = AddItemInMarc( $record, $biblionumber, $frameworkcode );
-
-Add an item in a MARC record and save the MARC record
-
-Function exported, but should NOT be used, unless you really know what you're doing
-
-=back
-
-=cut
-
-sub AddItemInMarc {
-
- # pass the MARC::Record to this function, and it will create the records in the marc tables
- my ( $record, $biblionumber, $frameworkcode ) = @_;
- my $newrec = &GetMarcBiblio($biblionumber);
-
- # create it
- my @fields = $record->fields();
- foreach my $field (@fields) {
- $newrec->append_fields($field);
- }
-
- # FIXME: should we be making sure the biblionumbers are the same?
- my $newbiblionumber =
- &ModBiblioMarc( $newrec, $biblionumber, $frameworkcode );
- return $newbiblionumber;
-}
-
=head2 z3950_extended_services
z3950_extended_services($serviceType,$serviceOptions,$record);
my ( $biblionumber ) = @_;
my $dbh = C4::Context->dbh;
my $query = "SELECT count(*)
- FROM items
- WHERE biblionumber=?";
+ FROM items
+ WHERE biblionumber=?";
my $sth = $dbh->prepare($query);
$sth->execute($biblionumber);
my $count = $sth->fetchrow;