# Suite 330, Boston, MA 02111-1307 USA
use strict;
-
-require Exporter;
# use utf8;
-use C4::Context;
use MARC::Record;
use MARC::File::USMARC;
use MARC::File::XML;
use ZOOM;
+
+use C4::Context;
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);
-# set the version for version checking
-$VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v).".".join( "_", map { sprintf "%03d", $_ } @v ); };
-
-@ISA = qw( Exporter );
-
-# EXPORTED FUNCTIONS.
-
-# to add biblios or items
-push @EXPORT, qw( &AddBiblio &AddItem );
-
-# to get something
-push @EXPORT, qw(
- &GetBiblio
- &GetBiblioData
- &GetBiblioItemData
- &GetBiblioItemInfosOf
- &GetBiblioItemByBiblioNumber
- &GetBiblioFromItemNumber
-
- &GetMarcItem
- &GetItem
- &GetItemInfosOf
- &GetItemStatus
- &GetItemLocation
- &GetLostItems
- &GetItemsForInventory
- &GetItemsCount
-
- &GetMarcNotes
- &GetMarcSubjects
- &GetMarcBiblio
- &GetMarcAuthors
- &GetMarcSeries
- &GetUsedMarcStructure
-
- &GetItemsInfo
- &GetItemsByBiblioitemnumber
- &GetItemnumberFromBarcode
- &get_itemnumbers_of
- &GetXmlBiblio
-
- &GetAuthorisedValueDesc
- &GetMarcStructure
- &GetMarcFromKohaField
- &GetFrameworkCode
- &GetPublisherNameFromIsbn
- &TransformKohaToMarc
-);
-
-# To modify something
-push @EXPORT, qw(
- &ModBiblio
- &ModItem
- &ModItemTransfer
- &ModBiblioframework
- &ModZebra
- &ModItemInMarc
- &ModItemInMarconefield
- &ModDateLastSeen
-);
-
-# To delete something
-push @EXPORT, qw(
- &DelBiblio
- &DelItem
-);
-
-# Internal functions
-# those functions are exported but should not be used
-# they are usefull is few circumstances, so are exported.
-# but don't use them unless you're a core developer ;-)
-push @EXPORT, qw(
- &ModBiblioMarc
- &AddItemInMarc
- &calculatelc
- &itemcalculator
-);
-
-# Others functions
-push @EXPORT, qw(
- &TransformMarcToKoha
- &TransformHtmlToMarc2
- &TransformHtmlToMarc
- &TransformHtmlToXml
- &PrepareItemrecordDisplay
- &char_decode
- &GetNoZebraIndexes
-);
+BEGIN {
+ $VERSION = 1.00;
+
+ require Exporter;
+ @ISA = qw( Exporter );
+
+ # to add biblios
+ push @EXPORT, qw(
+ &AddBiblio
+ );
+
+ # to get something
+ push @EXPORT, qw(
+ &GetBiblio
+ &GetBiblioData
+ &GetBiblioItemData
+ &GetBiblioItemInfosOf
+ &GetBiblioItemByBiblioNumber
+ &GetBiblioFromItemNumber
+
+ &GetMarcNotes
+ &GetMarcSubjects
+ &GetMarcBiblio
+ &GetMarcAuthors
+ &GetMarcSeries
+ GetMarcUrls
+ &GetUsedMarcStructure
+
+ &GetXmlBiblio
+
+ &GetAuthorisedValueDesc
+ &GetMarcStructure
+ &GetMarcFromKohaField
+ &GetFrameworkCode
+ &GetPublisherNameFromIsbn
+ &TransformKohaToMarc
+ );
+
+ # To modify something
+ push @EXPORT, qw(
+ &ModBiblio
+ &ModBiblioframework
+ &ModZebra
+ );
+
+ # To delete something
+ push @EXPORT, qw(
+ &DelBiblio
+ );
+
+ # Internal functions
+ # those functions are exported but should not be used
+ # they are usefull is few circumstances, so are exported.
+ # but don't use them unless you're a core developer ;-)
+ push @EXPORT, qw(
+ &ModBiblioMarc
+ );
+
+ # Others functions
+ push @EXPORT, qw(
+ &TransformMarcToKoha
+ &TransformHtmlToMarc2
+ &TransformHtmlToMarc
+ &TransformHtmlToXml
+ &PrepareItemrecordDisplay
+ &char_decode
+ &GetNoZebraIndexes
+ );
+}
=head1 NAME
=over 4
($biblionumber,$biblioitemnumber) = AddBiblio($record,$frameworkcode);
-Exported function (core API) for adding a new biblio to koha.
=back
+Exported function (core API) for adding a new biblio to koha.
+
+The first argument is a C<MARC::Record> object containing the
+bib to add, while the second argument is the desired MARC
+framework code.
+
+This function also accepts a third, optional argument: a hashref
+to additional options. The only defined option is C<defer_marc_save>,
+which if present and mapped to a true value, causes C<AddBiblio>
+to omit the call to save the MARC in C<bibilioitems.marc>
+and C<biblioitems.marcxml> This option is provided B<only>
+for the use of scripts such as C<bulkmarcimport.pl> that may need
+to do some manipulation of the MARC record for item parsing before
+saving it and which cannot afford the performance hit of saving
+the MARC record twice. Consequently, do not use that option
+unless you can guarantee that C<ModBiblioMarc> will be called.
+
=cut
sub AddBiblio {
- my ( $record, $frameworkcode ) = @_;
- my $biblionumber;
- my $biblioitemnumber;
+ my $record = shift;
+ my $frameworkcode = shift;
+ my $options = @_ ? shift : undef;
+ my $defer_marc_save = 0;
+ if (defined $options and exists $options->{'defer_marc_save'} and $options->{'defer_marc_save'}) {
+ $defer_marc_save = 1;
+ }
+
+ my ($biblionumber,$biblioitemnumber,$error);
my $dbh = C4::Context->dbh;
# transform the data into koha-table style data
my $olddata = TransformMarcToKoha( $dbh, $record, $frameworkcode );
- $biblionumber = _koha_add_biblio( $dbh, $olddata, $frameworkcode );
+ ($biblionumber,$error) = _koha_add_biblio( $dbh, $olddata, $frameworkcode );
$olddata->{'biblionumber'} = $biblionumber;
- $biblioitemnumber = _koha_add_biblioitem( $dbh, $olddata );
+ ($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 );
+ $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode ) unless $defer_marc_save;
&logaction(C4::Context->userenv->{'number'},"CATALOGUING","ADD",$biblionumber,"biblio")
if C4::Context->preference("CataloguingLog");
return ( $biblionumber, $biblioitemnumber );
}
-=head2 AddItem
-
-=over 2
-
- $biblionumber = AddItem( $record, $biblionumber)
- Exported function (core API) for adding a new item to Koha
-
-=back
-
-=cut
-
-sub AddItem {
- my ( $record, $biblionumber ) = @_;
- my $dbh = C4::Context->dbh;
-
- # add item in old-DB
- my $frameworkcode = GetFrameworkCode( $biblionumber );
- my $item = &TransformMarcToKoha( $dbh, $record, $frameworkcode );
-
- # 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 );
- }
- 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 );
- }
- 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")
- if C4::Context->preference("CataloguingLog");
-
- return ($item->{biblionumber}, $item->{biblioitemnumber},$itemnumber);
-}
-
=head2 ModBiblio
ModBiblio( $record,$biblionumber,$frameworkcode);
$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
- _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 );
- _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 there are no items with issues are still attached
- my $sth =
- $dbh->prepare(
- "SELECT itemnumber FROM items WHERE biblionumber=?");
+
+ # First make sure this biblio has no items attached
+ my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber=?");
$sth->execute($biblionumber);
- while ( my $itemnumber = $sth->fetchrow ) {
- my $issues = GetItemIssues($itemnumber);
- foreach my $issue (@$issues) {
- if ( ( $issue->{date_due} )
- && ( $issue->{date_due} ne "Available" ) )
- {
-
-#FIXME: we need a status system in Biblio like in Circ to return standard codes and messages
-# instead of hard-coded strings
- $error .=
-"Item is checked out to a patron -- you must return it before deleting the Biblio";
- }
- }
+ 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;
# Delete in Zebra. Be careful NOT to move this line after _koha_delete_biblio
# - 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 items
- my $items_sth =
- $dbh->prepare(
- "SELECT itemnumber FROM items WHERE biblioitemnumber=?");
- $items_sth->execute($biblioitemnumber);
- while ( my $itemnumber = $items_sth->fetchrow ) {
- $error = &_koha_delete_item( $dbh, $itemnumber );
- return $error if $error;
- }
}
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","DELETE",$biblionumber,"")
- if C4::Context->preference("CataloguingLog");
- return;
-}
-
-=head2 DelItem
-
-=over
-
-DelItem( $biblionumber, $itemnumber );
-Exported function (core API) for deleting an item record in Koha.
-
-=back
-
-=cut
-
-sub DelItem {
- my ( $biblionumber, $itemnumber ) = @_;
- my $dbh = C4::Context->dbh;
- &_koha_delete_item( $dbh, $itemnumber );
- # get the MARC record
- my $record = GetMarcBiblio($biblionumber);
- my $frameworkcode = GetFrameworkCode($biblionumber);
- # backup the record
- my $copy2deleted =
- $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
- $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
+ # 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 );
- #search item field code
- my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
- my @fields = $record->field($itemtag);
- # delete the item specified
- foreach my $field (@fields) {
- if ( $field->subfield($itemsubfield) eq $itemnumber ) {
- $record->delete_field($field);
- }
- }
- &ModBiblioMarc( $record, $biblionumber, $frameworkcode );
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","DELETE",$itemnumber,"item")
+ &logaction(C4::Context->userenv->{'number'},"CATALOGUING","DELETE",$biblionumber,"")
if C4::Context->preference("CataloguingLog");
+ return;
}
=head2 GetBiblioData
my ( $bibnum ) = @_;
my $dbh = C4::Context->dbh;
- my $query = "
- SELECT * , biblioitems.notes AS bnotes, 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;
return ($data);
} # sub GetBiblioData
-
-=head2 GetItemsInfo
-
-=over 4
-
- @results = &GetItemsInfo($biblionumber, $type);
-
-Returns information about books with the given biblionumber.
-
-C<$type> may be either C<intra> or anything else. If it is not set to
-C<intra>, then the search will exclude lost, very overdue, and
-withdrawn items.
-
-C<&GetItemsInfo> returns a list of references-to-hash. Each element
-contains a number of keys. Most of them are table items from the
-C<biblio>, C<biblioitems>, C<items>, and C<itemtypes> tables in the
-Koha database. Other keys include:
-
-=over 4
-
-=item C<$data-E<gt>{branchname}>
-
-The name (not the code) of the branch to which the book belongs.
-
-=item C<$data-E<gt>{datelastseen}>
-
-This is simply C<items.datelastseen>, except that while the date is
-stored in YYYY-MM-DD format in the database, here it is converted to
-DD/MM/YYYY format. A NULL date is returned as C<//>.
-
-=item C<$data-E<gt>{datedue}>
-
-=item C<$data-E<gt>{class}>
-
-This is the concatenation of C<biblioitems.classification>, the book's
-Dewey code, and C<biblioitems.subclass>.
-
-=item C<$data-E<gt>{ocount}>
-
-I think this is the number of copies of the book available.
-
-=item C<$data-E<gt>{order}>
-
-If this is set, it is set to C<One Order>.
-
-=back
-
-=back
-
-=cut
-
-sub GetItemsInfo {
- my ( $biblionumber, $type ) = @_;
- my $dbh = C4::Context->dbh;
- 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
- ";
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber);
- my $i = 0;
- my @results;
- my ( $date_due, $count_reserves );
-
- 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'} );
- }
- if ( $datedue eq '' ) {
- #$datedue="Available";
- my ( $restype, $reserves ) =
- C4::Reserves::CheckReserves( $data->{'itemnumber'} );
- if ($restype) {
-
- #$datedue=$restype;
- $count_reserves = $restype;
- }
- }
- $isth->finish;
-
- #get branch information.....
- my $bsth = $dbh->prepare(
- "SELECT * FROM branches WHERE branchcode = ?
- "
- );
- $bsth->execute( $data->{'holdingbranch'} );
- 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;
-
- # get notforloan complete status if applicable
- my $sthnflstatus = $dbh->prepare(
- 'SELECT authorised_value
- FROM marc_subfield_structure
- WHERE kohafield="items.notforloan"
- '
- );
-
- $sthnflstatus->execute;
- my ($authorised_valuecode) = $sthnflstatus->fetchrow;
- if ($authorised_valuecode) {
- $sthnflstatus = $dbh->prepare(
- "SELECT lib FROM authorised_values
- WHERE category=?
- AND authorised_value=?"
- );
- $sthnflstatus->execute( $authorised_valuecode,
- $data->{itemnotforloan} );
- my ($lib) = $sthnflstatus->fetchrow;
- $data->{notforloan} = $lib;
- }
-
- # my stack procedures
- my $stackstatus = $dbh->prepare(
- 'SELECT authorised_value
- FROM marc_subfield_structure
- WHERE kohafield="items.stack"
- '
- );
- $stackstatus->execute;
-
- ($authorised_valuecode) = $stackstatus->fetchrow;
- if ($authorised_valuecode) {
- $stackstatus = $dbh->prepare(
- "SELECT lib
- FROM authorised_values
- WHERE category=?
- AND authorised_value=?
- "
- );
- $stackstatus->execute( $authorised_valuecode, $data->{stack} );
- my ($lib) = $stackstatus->fetchrow;
- $data->{stack} = $lib;
- }
- $results[$i] = $data;
- $i++;
- }
- $sth->finish;
-
- return (@results);
-}
-
-=head2 getitemstatus
-
-=over 4
-
-$itemstatushash = &getitemstatus($fwkcode);
-returns information about status.
-Can be MARC dependant.
-fwkcode is optional.
-But basically could be can be loan or not
-Create a status selector with the following code
-
-=head3 in PERL SCRIPT
-
-my $itemstatushash = getitemstatus;
-my @itemstatusloop;
-foreach my $thisstatus (keys %$itemstatushash) {
- my %row =(value => $thisstatus,
- statusname => $itemstatushash->{$thisstatus}->{'statusname'},
- );
- push @itemstatusloop, \%row;
-}
-$template->param(statusloop=>\@itemstatusloop);
-
-
-=head3 in TEMPLATE
-
- <select name="statusloop">
- <option value="">Default</option>
- <!-- TMPL_LOOP name="statusloop" -->
- <option value="<!-- TMPL_VAR name="value" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="statusname" --></option>
- <!-- /TMPL_LOOP -->
- </select>
-
-=cut
-
-sub GetItemStatus {
-
- # returns a reference to a hash of references to status...
- my ($fwk) = @_;
- my %itemstatus;
- my $dbh = C4::Context->dbh;
- my $sth;
- $fwk = '' unless ($fwk);
- my ( $tag, $subfield ) =
- GetMarcFromKohaField( "items.notforloan", $fwk );
- if ( $tag and $subfield ) {
- my $sth =
- $dbh->prepare(
-"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"
- );
- $authvalsth->execute($authorisedvaluecat);
- while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
- $itemstatus{$authorisedvalue} = $lib;
- }
- $authvalsth->finish;
- return \%itemstatus;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- $sth->finish;
- }
-
- #No authvalue list
- #build default
- $itemstatus{"1"} = "Not For Loan";
- return \%itemstatus;
-}
-
-=head2 getitemlocation
-
-=over 4
-
-$itemlochash = &getitemlocation($fwk);
-returns informations about location.
-where fwk stands for an optional framework code.
-Create a location selector with the following code
-
-=head3 in PERL SCRIPT
-
-my $itemlochash = getitemlocation;
-my @itemlocloop;
-foreach my $thisloc (keys %$itemlochash) {
- my $selected = 1 if $thisbranch eq $branch;
- my %row =(locval => $thisloc,
- selected => $selected,
- locname => $itemlochash->{$thisloc},
- );
- push @itemlocloop, \%row;
-}
-$template->param(itemlocationloop => \@itemlocloop);
-
-=head3 in TEMPLATE
-
-<select name="location">
- <option value="">Default</option>
-<!-- TMPL_LOOP name="itemlocationloop" -->
- <option value="<!-- TMPL_VAR name="locval" -->" <!-- TMPL_IF name="selected" -->selected<!-- /TMPL_IF -->><!-- TMPL_VAR name="locname" --></option>
-<!-- /TMPL_LOOP -->
-</select>
-
-=back
-
-=cut
-
-sub GetItemLocation {
-
- # returns a reference to a hash of references to location...
- my ($fwk) = @_;
- my %itemlocation;
- my $dbh = C4::Context->dbh;
- my $sth;
- $fwk = '' unless ($fwk);
- my ( $tag, $subfield ) =
- GetMarcFromKohaField( "items.location", $fwk );
- if ( $tag and $subfield ) {
- my $sth =
- $dbh->prepare(
-"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"
- );
- $authvalsth->execute($authorisedvaluecat);
- while ( my ( $authorisedvalue, $lib ) = $authvalsth->fetchrow ) {
- $itemlocation{$authorisedvalue} = $lib;
- }
- $authvalsth->finish;
- return \%itemlocation;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- $sth->finish;
- }
-
- #No authvalue list
- #build default
- $itemlocation{"1"} = "Not For Loan";
- return \%itemlocation;
-}
-
-=head2 GetLostItems
-
-$items = GetLostItems($where,$orderby);
-
-This function get the items lost into C<$items>.
-
-=over 2
-
-=item input:
-C<$where> is a hashref. it containts a field of the items table as key
-and the value to match as value.
-C<$orderby> is a field of the items table.
-
-=item return:
-C<$items> is a reference to an array full of hasref which keys are items' table column.
-
-=item usage in the perl script:
-
-my %where;
-$where{barcode} = 0001548;
-my $items = GetLostItems( \%where, "homebranch" );
-$template->param(itemsloop => $items);
-
-=back
-
-=cut
-
-sub GetLostItems {
- # Getting input args.
- my $where = shift;
- my $orderby = shift;
- my $dbh = C4::Context->dbh;
-
- my $query = "
- SELECT *
- FROM items
- WHERE itemlost IS NOT NULL
- AND itemlost <> 0
- ";
- foreach my $key (keys %$where) {
- $query .= " AND " . $key . " LIKE '%" . $where->{$key} . "%'";
- }
- $query .= " ORDER BY ".$orderby if defined $orderby;
-
- my $sth = $dbh->prepare($query);
- $sth->execute;
- my @items;
- while ( my $row = $sth->fetchrow_hashref ){
- push @items, $row;
- }
- return \@items;
-}
-
-=head2 GetItemsForInventory
-
-$itemlist = GetItemsForInventory($minlocation,$maxlocation,$datelastseen,$offset,$size)
-
-Retrieve a list of title/authors/barcode/callnumber, for biblio inventory.
-
-The sub returns a list of hashes, containing itemnumber, author, title, barcode & item callnumber.
-It is ordered by callnumber,title.
-
-The minlocation & maxlocation parameters are used to specify a range of item callnumbers
-the datelastseen can be used to specify that you want to see items not seen since a past date only.
-offset & size can be used to retrieve only a part of the whole listing (defaut behaviour)
-
-=cut
-
-sub GetItemsForInventory {
- my ( $minlocation, $maxlocation,$location, $datelastseen, $branch, $offset, $size ) = @_;
- my $dbh = C4::Context->dbh;
- my $sth;
- if ($datelastseen) {
- $datelastseen=format_date_in_iso($datelastseen);
- my $query =
- "SELECT itemnumber,barcode,itemcallnumber,title,author,biblio.biblionumber,datelastseen
- FROM items
- LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
- WHERE itemcallnumber>= ?
- AND itemcallnumber <=?
- AND (datelastseen< ? OR datelastseen IS NULL)";
- $query.= " AND items.location=".$dbh->quote($location) if $location;
- $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
- $query .= " ORDER BY itemcallnumber,title";
- $sth = $dbh->prepare($query);
- $sth->execute( $minlocation, $maxlocation, $datelastseen );
- }
- else {
- my $query ="
- SELECT itemnumber,barcode,itemcallnumber,biblio.biblionumber,title,author,datelastseen
- FROM items
- LEFT JOIN biblio ON items.biblionumber=biblio.biblionumber
- WHERE itemcallnumber>= ?
- AND itemcallnumber <=?";
- $query.= " AND items.location=".$dbh->quote($location) if $location;
- $query.= " AND items.homebranch=".$dbh->quote($branch) if $branch;
- $query .= " ORDER BY itemcallnumber,title";
- $sth = $dbh->prepare($query);
- $sth->execute( $minlocation, $maxlocation );
- }
- my @results;
- while ( my $row = $sth->fetchrow_hashref ) {
- $offset-- if ($offset);
- $row->{datelastseen}=format_date($row->{datelastseen});
- if ( ( !$offset ) && $size ) {
- push @results, $row;
- $size--;
- }
- }
- return \@results;
-}
-
=head2 &GetBiblioItemData
=over 4
#'
sub GetBiblioItemData {
- my ($bibitem) = @_;
+ 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 = ? and biblioitems.itemtype = itemtypes.itemtype"
- );
+ my $query = "SELECT *,biblioitems.notes AS bnotes
+ FROM biblio LEFT JOIN biblioitems on biblio.biblionumber=biblioitems.biblioitemnumber ";
+ unless(C4::Context->preference('item-level_itypes')) {
+ $query .= "LEFT JOIN itemtypes on biblioitems.itemtype=itemtypes.itemtype ";
+ }
+ $query .= " WHERE biblioitemnumber = ? ";
+ my $sth = $dbh->prepare($query);
my $data;
-
- $sth->execute($bibitem);
-
+ $sth->execute($biblioitemnumber);
$data = $sth->fetchrow_hashref;
-
$sth->finish;
return ($data);
} # sub &GetBiblioItemData
-=head2 GetItemnumberFromBarcode
-
-=over 4
-
-$result = GetItemnumberFromBarcode($barcode);
-
-=back
-
-=cut
-
-sub GetItemnumberFromBarcode {
- my ($barcode) = @_;
- my $dbh = C4::Context->dbh;
-
- my $rq =
- $dbh->prepare("SELECT itemnumber from items where items.barcode=?");
- $rq->execute($barcode);
- my ($result) = $rq->fetchrow;
- return ($result);
-}
-
=head2 GetBiblioItemByBiblioNumber
=over 4
sub GetBiblioItemByBiblioNumber {
my ($biblionumber) = @_;
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
+ my $sth = $dbh->prepare("Select * FROM biblioitems WHERE biblionumber = ?");
my $count = 0;
my @results;
=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);
sub GetBiblio {
my ($biblionumber) = @_;
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
+ my $sth = $dbh->prepare("SELECT * FROM biblio WHERE biblionumber = ?");
my $count = 0;
my @results;
$sth->execute($biblionumber);
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
-
-my @itemnumbers_of = get_itemnumbers_of(@biblionumbers);
-
-Given a list of biblionumbers, return the list of corresponding itemnumbers
-for each biblionumber.
-
-Return a reference on a hash where keys are biblionumbers and values are
-references on array of itemnumbers.
-
-=back
-
-=cut
-
-sub get_itemnumbers_of {
- my @biblionumbers = @_;
-
- my $dbh = C4::Context->dbh;
-
- my $query = '
- SELECT itemnumber,
- biblionumber
- FROM items
- WHERE biblionumber IN (?' . ( ',?' x scalar @biblionumbers - 1 ) . ')
- ';
- my $sth = $dbh->prepare($query);
- $sth->execute(@biblionumbers);
-
- my %itemnumbers_of;
-
- while ( my ( $itemnumber, $biblionumber ) = $sth->fetchrow_array ) {
- push @{ $itemnumbers_of{$biblionumber} }, $itemnumber;
- }
-
- return \%itemnumbers_of;
-}
-
-=head2 GetItemInfosOf
-
-=over 4
-
-GetItemInfosOf(@itemnumbers);
-
-=back
-
-=cut
-
-sub GetItemInfosOf {
- my @itemnumbers = @_;
-
- my $query = '
- SELECT *
- FROM items
- WHERE itemnumber IN (' . join( ',', @itemnumbers ) . ')
- ';
- return get_infos_of( $query, 'itemnumber' );
-}
-
-=head2 GetItemsByBiblioitemnumber
-
-=over 4
-
-GetItemsByBiblioitemnumber($biblioitemnumber);
-
-Returns an arrayref of hashrefs suitable for use in a TMPL_LOOP
-Called by moredetail.pl
-
-=back
-
-=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 $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
- 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'};
- }
- 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 = ?
- AND issues.borrowernumber = borrowers.borrowernumber
- AND returndate is not NULL
- ORDER BY returndate desc,timestamp desc LIMIT 3";
- $sth2 = $dbh->prepare($query2) || die $dbh->errstr;
- $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++;
- }
- $sth2->finish;
- push(@results,$data);
- }
- $sth->finish;
- return (\@results);
-}
-
-
=head2 GetBiblioItemInfosOf
=over 4
# check that framework exists
$sth =
$dbh->prepare(
- "select count(*) from marc_tag_structure where frameworkcode=?");
+ "SELECT COUNT(*) FROM marc_tag_structure WHERE frameworkcode=?");
$sth->execute($frameworkcode);
my ($total) = $sth->fetchrow;
$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 );
{
$res->{$tag}->{lib} =
( $forlibrarian or !$libopac ) ? $liblibrarian : $libopac;
- # why the hell do we need to explicitly decode utf8 ?
- # that's a good question, but we must do it...
- $res->{$tab}->{tab} = ""; # XXX
+ $res->{$tab}->{tab} = "";
$res->{$tag}->{mandatory} = $mandatory;
$res->{$tag}->{repeatable} = $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);
my $biblionumber = shift;
my $dbh = C4::Context->dbh;
my $sth =
- $dbh->prepare("select marcxml from biblioitems where biblionumber=? ");
+ $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
$sth->execute($biblionumber);
my ($marcxml) = $sth->fetchrow;
MARC::File::XML->default_record_format(C4::Context->preference('marcflavour'));
$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
my ( $biblionumber ) = @_;
my $dbh = C4::Context->dbh;
my $sth =
- $dbh->prepare("select marcxml from biblioitems where biblionumber=? ");
+ $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
$sth->execute($biblionumber);
my ($marcxml) = $sth->fetchrow;
return $marcxml;
=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
# tagslib useful for UNIMARC author reponsabilities
my $tagslib = &GetMarcStructure( 1, '' ); # FIXME : we don't have the framework available, we take the default framework. May be bugguy on some setups, will be usually correct.
if ( $marcflavour eq "MARC21" ) {
- $mintag = "100";
- $maxtag = "111";
+ $mintag = "700";
+ $maxtag = "720";
}
- else { # assume unimarc if not marc21
- $mintag = "701";
+ elsif ( $marcflavour eq "UNIMARC" ) { # assume unimarc if not marc21
+ $mintag = "700";
$maxtag = "712";
}
-
+ 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;
- my $and ;
+ # if there is an authority link, build the link with Koha-Auth-Number: subfield9
+ my $subfield9 = $field->subfield('9');
for my $authors_subfield (@subfields) {
- if (
- $marcflavour ne 'MARC21'
- and (
- ($authors_subfield->[0] eq '3') or
- ($authors_subfield->[0] eq '5')
- )
- )
- {
- next;
+ # 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 = $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" });
}
- if ($count_auth ne '0'){
- $and = " and au:";
+ 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 };
}
+ 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++;
- my $subfieldcode = $authors_subfield->[0];
- my $value;
- # deal with UNIMARC author responsibility
- if (
- $marcflavour ne 'MARC21'
- and ($authors_subfield->[0] eq '4')
- )
- {
- $value = "(".GetAuthorisedValueDesc( $field->tag(), $authors_subfield->[0], $authors_subfield->[1], '', $tagslib ).")";
- } else {
- $value = $authors_subfield->[1];
- }
- $hash{tag} = $field->tag;
- $hash{value} .= $value . " " if ($subfieldcode != 9) ;
- $hash{link} .= $value if ($subfieldcode eq 9);
}
- push @marcauthors, \%hash;
+ push @marcauthors, { MARCAUTHOR_SUBFIELDS_LOOP => \@subfields_loop };
}
return \@marcauthors;
}
+=head2 GetMarcUrls
+
+=over 4
+
+$marcurls = GetMarcUrls($record,$marcflavour);
+Returns arrayref of URLs from MARC data, suitable to pass to tmpl loop.
+Assumes web resources (not uncommon in MARC21 to omit resource type ind)
+
+=back
+
+=cut
+
+sub GetMarcUrls {
+ my ($record, $marcflavour) = @_;
+ my @marcurls;
+ my $marcurl;
+ for my $field ($record->field('856')) {
+ my $url = $field->subfield('u');
+ my @notes;
+ for my $note ( $field->subfield('z')) {
+ push @notes , {note => $note};
+ }
+ $marcurl = { MARCURL => $url,
+ notes => \@notes,
+ };
+ 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;
+ }
+ push @marcurls, $marcurl;
+ }
+ return \@marcurls;
+} #end GetMarcUrls
+
=head2 GetMarcSeries
=over 4
-$marcseriessarray = GetMarcSeries($record,$marcflavour);
+$marcseriesarray = GetMarcSeries($record,$marcflavour);
Get all series from the MARC record and returns them in an array.
The series are stored in differents places depending on MARC flavour
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 };
sub GetFrameworkCode {
my ( $biblionumber ) = @_;
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("select frameworkcode from biblio where biblionumber=?");
+ my $sth = $dbh->prepare("SELECT frameworkcode FROM biblio WHERE biblionumber=?");
$sth->execute($biblionumber);
my ($frameworkcode) = $sth->fetchrow;
return $frameworkcode;
my $dbh = C4::Context->dbh;
my $sth =
$dbh->prepare(
- "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
+ "SELECT tagfield,tagsubfield FROM marc_subfield_structure WHERE frameworkcode=? AND kohafield=?"
);
my $record = MARC::Record->new();
foreach (keys %{$hash}) {
if ( !defined $sth ) {
my $dbh = C4::Context->dbh;
$sth = $dbh->prepare(
- "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
+ "SELECT tagfield,tagsubfield FROM marc_subfield_structure WHERE frameworkcode=? AND kohafield=?"
);
}
$sth->execute( $frameworkcode, $kohafieldname );
}
$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 ) = @_;
-
- # FIXME :: This query is unused..
- # my $sth =
- # $dbh->prepare(
- #"select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
- # );
-
+ my ( $dbh, $record, $frameworkcode, $limit_table ) = @_;
+
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 );
+
+ unless (defined $inverted_field_map) {
+ $inverted_field_map = _get_inverted_marc_field_map();
}
- $sth2 = $dbh->prepare("SHOW COLUMNS from items");
- $sth2->execute;
- while ( ($field) = $sth2->fetchrow ) {
- $result =
- &TransformMarcToKohaOneField( "items", $field, $record, $result,
- $frameworkcode );
+
+ my %tables = ();
+ if ($limit_table eq 'items') {
+ $tables{'items'} = 1;
+ } else {
+ $tables{'items'} = 1;
+ $tables{'biblio'} = 1;
+ $tables{'biblioitems'} = 1;
+ }
+
+ # 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 $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 ( $itemtagfield, $itemtagsubfield ) =
&GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
my $tagslib = &GetMarcStructure( 1, $frameworkcode );
- my $itemrecord = GetMarcItem( $bibnum, $itemnum) if ($itemnum);
+ my $itemrecord = C4::Items::GetMarcItem( $bibnum, $itemnum) if ($itemnum);
my @loop_data;
my $authorised_values_sth =
$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"
);
foreach my $tag ( sort keys %{$tagslib} ) {
my $previous_tag = '';
{
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 {
#
# we use zebra, just fill zebraqueue table
#
- my $sth=$dbh->prepare("insert into zebraqueue (biblio_auth_number ,server,operation) values(?,?,?)");
+ my $sth=$dbh->prepare("INSERT INTO zebraqueue (biblio_auth_number,server,operation) VALUES(?,?,?)");
$sth->execute($biblionumber,$server,$op);
$sth->finish;
}
$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;
}
-=head2 MARCitemchange
+=head2 _find_value
=over 4
-&MARCitemchange( $record, $itemfield, $newvalue )
+($indicators, $value) = _find_value($tag, $subfield, $record,$encoding);
-Function to update a single value in an item field.
-Used twice, could probably be replaced by something else, but works well...
+Find the given $subfield in the given $tag in the given
+MARC::Record $record. If the subfield is found, returns
+the (indicators, value) pair; otherwise, (undef, undef) is
+returned.
-=back
+PROPOSITION :
+Such a function is used in addbiblio AND additem and serial-edit and maybe could be used in Authorities.
+I suggest we export it from this module.
=back
=cut
-sub MARCitemchange {
- my ( $record, $itemfield, $newvalue ) = @_;
- my $dbh = C4::Context->dbh;
-
- my ( $tagfield, $tagsubfield ) =
- GetMarcFromKohaField( $itemfield, "" );
- if ( ($tagfield) && ($tagsubfield) ) {
- my $tag = $record->field($tagfield);
- if ($tag) {
- $tag->update( $tagsubfield => $newvalue );
- $record->delete_field($tag);
- $record->insert_fields_ordered($tag);
+sub _find_value {
+ my ( $tagfield, $insubfield, $record, $encoding ) = @_;
+ my @result;
+ my $indicator;
+ if ( $tagfield < 10 ) {
+ if ( $record->field($tagfield) ) {
+ push @result, $record->field($tagfield)->data();
+ }
+ else {
+ push @result, "";
+ }
+ }
+ else {
+ foreach my $field ( $record->field($tagfield) ) {
+ my @subfields = $field->subfields();
+ foreach my $subfield (@subfields) {
+ if ( @$subfield[0] eq $insubfield ) {
+ push @result, @$subfield[1];
+ $indicator = $field->indicator(1) . $field->indicator(2);
+ }
+ }
}
}
+ return ( $indicator, @result );
}
-=head2 _koha_add_biblio
+=head2 _koha_marc_update_bib_ids
=over 4
-_koha_add_biblio($dbh,$biblioitem);
+_koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
-Internal function to add a biblio ($biblio is a hash with the values)
+Internal function to add or update biblionumber and biblioitemnumber to
+the MARC XML.
=back
=cut
-sub _koha_add_biblio {
- my ( $dbh, $biblio, $frameworkcode ) = @_;
- my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
- $sth->execute;
- my $data = $sth->fetchrow_arrayref;
- my $biblionumber = $$data[0] + 1;
- my $series = 0;
+sub _koha_marc_update_bib_ids {
+ my ($record, $frameworkcode, $biblionumber, $biblioitemnumber) = @_;
- if ( $biblio->{'seriestitle'} ) { $series = 1 }
- $sth->finish;
- $sth = $dbh->prepare(
- "INSERT INTO biblio
- SET biblionumber = ?, title = ?, author = ?, copyrightdate = ?, serial = ?, seriestitle = ?, notes = ?, abstract = ?, unititle = ?, frameworkcode = ? "
- );
- $sth->execute(
- $biblionumber, $biblio->{'title'},
- $biblio->{'author'}, $biblio->{'copyrightdate'},
- $biblio->{'serial'}, $biblio->{'seriestitle'},
- $biblio->{'notes'}, $biblio->{'abstract'},
- $biblio->{'unititle'}, $frameworkcode
- );
+ # 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);
- $sth->finish;
- return ($biblionumber);
-}
+ if ($biblio_tag != $biblioitem_tag) {
+ # biblionumber & biblioitemnumber are in different fields
-=head2 _find_value
+ # 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 );
+ }
-=over 4
+ # drop old field and create new one...
+ $old_field = $record->field($biblio_tag);
+ $record->delete_field($old_field);
+ $record->append_fields($new_field);
-($indicators, $value) = _find_value($tag, $subfield, $record,$encoding);
+ # 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);
-Find the given $subfield in the given $tag in the given
-MARC::Record $record. If the subfield is found, returns
-the (indicators, value) pair; otherwise, (undef, undef) is
-returned.
+ } 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
+ );
-PROPOSITION :
-Such a function is used in addbiblio AND additem and serial-edit and maybe could be used in Authorities.
-I suggest we export it from this module.
+ # 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 ($biblionumber,$error) = _koha_add_biblio($dbh,$biblioitem);
+
+Internal function to add a biblio ($biblio is a hash with the values)
=back
=cut
-sub _find_value {
- my ( $tagfield, $insubfield, $record, $encoding ) = @_;
- my @result;
- my $indicator;
- if ( $tagfield < 10 ) {
- if ( $record->field($tagfield) ) {
- push @result, $record->field($tagfield)->data();
- }
- else {
- push @result, "";
- }
- }
- else {
- foreach my $field ( $record->field($tagfield) ) {
- my @subfields = $field->subfields();
- foreach my $subfield (@subfields) {
- if ( @$subfield[0] eq $insubfield ) {
- push @result, @$subfield[1];
- $indicator = $field->indicator(1) . $field->indicator(2);
- }
- }
- }
+sub _koha_add_biblio {
+ my ( $dbh, $biblio, $frameworkcode ) = @_;
+
+ my $error;
+
+ # set the series flag
+ my $serial = 0;
+ if ( $biblio->{'seriestitle'} ) { $serial = 1 };
+
+ my $query =
+ "INSERT INTO biblio
+ SET frameworkcode = ?,
+ author = ?,
+ title = ?,
+ unititle =?,
+ notes = ?,
+ serial = ?,
+ seriestitle = ?,
+ copyrightdate = ?,
+ datecreated=NOW(),
+ abstract = ?
+ ";
+ my $sth = $dbh->prepare($query);
+ $sth->execute(
+ $frameworkcode,
+ $biblio->{'author'},
+ $biblio->{'title'},
+ $biblio->{'unititle'},
+ $biblio->{'notes'},
+ $serial,
+ $biblio->{'seriestitle'},
+ $biblio->{'copyrightdate'},
+ $biblio->{'abstract'}
+ );
+
+ my $biblionumber = $dbh->{'mysql_insertid'};
+ if ( $dbh->errstr ) {
+ $error.="ERROR in _koha_add_biblio $query".$dbh->errstr;
+ warn $error;
}
- return ( $indicator, @result );
+
+ $sth->finish();
+ #warn "LEAVING _koha_add_biblio: ".$biblionumber."\n";
+ return ($biblionumber,$error);
}
=head2 _koha_modify_biblio
=over 4
-$biblionumber = _koha_modify_biblio($dbh,$biblio);
+my ($biblionumber,$error) == _koha_modify_biblio($dbh,$biblio,$frameworkcode);
+
Internal function for updating the biblio table
=back
=cut
sub _koha_modify_biblio {
- my ( $dbh, $biblio ) = @_;
- # FIXME: this code could be made more portable by not hard-coding
- # the values that are supposed to be in biblio table
- my $query = qq{
+ my ( $dbh, $biblio, $frameworkcode ) = @_;
+ my $error;
+
+ my $query = "
UPDATE biblio
- SET title = ?,
+ SET frameworkcode = ?,
author = ?,
- abstract = ?,
- copyrightdate = ?,
- seriestitle = ?,
- serial = ?,
+ title = ?,
unititle = ?,
- notes = ?
+ notes = ?,
+ serial = ?,
+ seriestitle = ?,
+ copyrightdate = ?,
+ abstract = ?
WHERE biblionumber = ?
- };
+ "
+ ;
my $sth = $dbh->prepare($query);
$sth->execute(
- $biblio->{'title'},
+ $frameworkcode,
$biblio->{'author'},
- $biblio->{'abstract'},
- $biblio->{'copyrightdate'},
- $biblio->{'seriestitle'},
- $biblio->{'serial'},
+ $biblio->{'title'},
$biblio->{'unititle'},
$biblio->{'notes'},
+ $biblio->{'serial'},
+ $biblio->{'seriestitle'},
+ $biblio->{'copyrightdate'},
+ $biblio->{'abstract'},
$biblio->{'biblionumber'}
) if $biblio->{'biblionumber'};
-
- warn $sth->err if $sth->err;
- warn "BIG ERROR :: No biblionumber for $biblio->{title}" if $biblio->{biblionumber} !~ /\d+/; # if it is not a number
- return ( $biblio->{'biblionumber'} );
+
+ if ( $dbh->errstr || !$biblio->{'biblionumber'} ) {
+ $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
-_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 $query;
-##Recalculate LC in case it changed --TG
-
- $biblioitem->{'itemtype'} = $dbh->quote( $biblioitem->{'itemtype'} );
- $biblioitem->{'url'} = $dbh->quote( $biblioitem->{'url'} );
- $biblioitem->{'isbn'} = $dbh->quote( $biblioitem->{'isbn'} );
- $biblioitem->{'issn'} = $dbh->quote( $biblioitem->{'issn'} );
- $biblioitem->{'publishercode'} =
- $dbh->quote( $biblioitem->{'publishercode'} );
- $biblioitem->{'publicationyear'} =
- $dbh->quote( $biblioitem->{'publicationyear'} );
- $biblioitem->{'classification'} =
- $dbh->quote( $biblioitem->{'classification'} );
- $biblioitem->{'dewey'} = $dbh->quote( $biblioitem->{'dewey'} );
- $biblioitem->{'subclass'} = $dbh->quote( $biblioitem->{'subclass'} );
- $biblioitem->{'illus'} = $dbh->quote( $biblioitem->{'illus'} );
- $biblioitem->{'pages'} = $dbh->quote( $biblioitem->{'pages'} );
- $biblioitem->{'volumeddesc'} = $dbh->quote( $biblioitem->{'volumeddesc'} );
- $biblioitem->{'bnotes'} = $dbh->quote( $biblioitem->{'bnotes'} );
- $biblioitem->{'size'} = $dbh->quote( $biblioitem->{'size'} );
- $biblioitem->{'place'} = $dbh->quote( $biblioitem->{'place'} );
- $biblioitem->{'collectiontitle'} = $dbh->quote( $biblioitem->{'collectiontitle'} );
- $biblioitem->{'collectionissn'} = $dbh->quote( $biblioitem->{'collectionissn'} );
- $biblioitem->{'collectionvolume'} = $dbh->quote( $biblioitem->{'collectionvolume'} );
- $biblioitem->{'editionstatement'} = $dbh->quote( $biblioitem->{'editionstatement'} );
- $biblioitem->{'editionresponsibility'} = $dbh->quote( $biblioitem->{'editionresponsibility'} );
- $biblioitem->{'ccode'} = $dbh->quote( $biblioitem->{'ccode'} );
- $biblioitem->{'biblionumber'} =
- $dbh->quote( $biblioitem->{'biblionumber'} );
-
- $query = "UPDATE biblioitems SET
- itemtype = $biblioitem->{'itemtype'},
- url = $biblioitem->{'url'},
- isbn = $biblioitem->{'isbn'},
- issn = $biblioitem->{'issn'},
- publishercode = $biblioitem->{'publishercode'},
- publicationyear = $biblioitem->{'publicationyear'},
- classification = $biblioitem->{'classification'},
- dewey = $biblioitem->{'dewey'},
- subclass = $biblioitem->{'subclass'},
- illus = $biblioitem->{'illus'},
- pages = $biblioitem->{'pages'},
- volumeddesc = $biblioitem->{'volumeddesc'},
- notes = $biblioitem->{'bnotes'},
- size = $biblioitem->{'size'},
- place = $biblioitem->{'place'},
- collectiontitle = $biblioitem->{'collectiontitle'},
- collectionissn = $biblioitem->{'collectionissn'},
- collectionvolume= $biblioitem->{'collectionvolume'},
- editionstatement= $biblioitem->{'editionstatement'},
- editionresponsibility= $biblioitem->{'editionresponsibility'},
- ccode = $biblioitem->{'ccode'}
- where biblionumber = $biblioitem->{'biblionumber'}";
-
- $dbh->do($query);
+ my $error;
+
+ # 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 = ?,
+ itemtype = ?,
+ isbn = ?,
+ issn = ?,
+ publicationyear = ?,
+ publishercode = ?,
+ 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 = ?
+ 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->{'url'},
+ $biblioitem->{'biblioitems.cn_source'},
+ $biblioitem->{'cn_class'},
+ $biblioitem->{'cn_item'},
+ $biblioitem->{'cn_suffix'},
+ $cn_sort,
+ $biblioitem->{'totalissues'},
+ $biblioitem->{'biblioitemnumber'}
+ );
if ( $dbh->errstr ) {
- warn "ERROR in _koha_modify_biblioitem $query";
+ $error.="ERROR in _koha_modify_biblioitem_nonmarc $query".$dbh->errstr;
+ warn $error;
}
+ return ($biblioitem->{'biblioitemnumber'},$error);
}
=head2 _koha_add_biblioitem
=over 4
-_koha_add_biblioitem( $dbh, $biblioitem );
+my ($biblioitemnumber,$error) = _koha_add_biblioitem( $dbh, $biblioitem );
Internal function to add a biblioitem
sub _koha_add_biblioitem {
my ( $dbh, $biblioitem ) = @_;
-
- # my $dbh = C4Connect;
- my $sth = $dbh->prepare("SELECT max(biblioitemnumber) FROM biblioitems");
- my $data;
- my $bibitemnum;
-
- $sth->execute;
- $data = $sth->fetchrow_arrayref;
- $bibitemnum = $$data[0] + 1;
-
- $sth->finish;
-
- $sth = $dbh->prepare(
- "INSERT INTO biblioitems SET
- biblioitemnumber = ?, biblionumber = ?,
- volume = ?, number = ?,
- classification = ?, itemtype = ?,
- url = ?, isbn = ?,
- issn = ?, dewey = ?,
- subclass = ?, publicationyear = ?,
- publishercode = ?, volumedate = ?,
- volumeddesc = ?, illus = ?,
- pages = ?, notes = ?,
- size = ?, lccn = ?,
- marc = ?, lcsort = ?,
- place = ?, ccode = ?,
- collectiontitle = ?, collectionissn = ?,
- collectionvolume = ?, editionstatement= ?,
- editionresponsibility= ?
- "
- );
- my ($lcsort) =
- calculatelc( $biblioitem->{'classification'} )
- . $biblioitem->{'subclass'};
+ my $error;
+
+ my ($cn_sort) = GetClassSort($biblioitem->{'biblioitems.cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
+ my $query =
+ "INSERT INTO biblioitems SET
+ biblionumber = ?,
+ volume = ?,
+ number = ?,
+ itemtype = ?,
+ isbn = ?,
+ issn = ?,
+ publicationyear = ?,
+ publishercode = ?,
+ volumedate = ?,
+ volumedesc = ?,
+ collectiontitle = ?,
+ collectionissn = ?,
+ collectionvolume= ?,
+ editionstatement= ?,
+ editionresponsibility = ?,
+ illus = ?,
+ pages = ?,
+ notes = ?,
+ size = ?,
+ place = ?,
+ lccn = ?,
+ marc = ?,
+ url = ?,
+ cn_source = ?,
+ cn_class = ?,
+ cn_item = ?,
+ cn_suffix = ?,
+ cn_sort = ?,
+ totalissues = ?
+ ";
+ my $sth = $dbh->prepare($query);
$sth->execute(
- $bibitemnum, $biblioitem->{'biblionumber'},
- $biblioitem->{'volume'}, $biblioitem->{'number'},
- $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
- $biblioitem->{'url'}, $biblioitem->{'isbn'},
- $biblioitem->{'issn'}, $biblioitem->{'dewey'},
- $biblioitem->{'subclass'}, $biblioitem->{'publicationyear'},
- $biblioitem->{'publishercode'}, $biblioitem->{'volumedate'},
- $biblioitem->{'volumeddesc'}, $biblioitem->{'illus'},
- $biblioitem->{'pages'}, $biblioitem->{'bnotes'},
- $biblioitem->{'size'}, $biblioitem->{'lccn'},
- $biblioitem->{'marc'}, $biblioitem->{'place'},
- $lcsort, $biblioitem->{'ccode'},
- $biblioitem->{'collectiontitle'},$biblioitem->{'collectionissn'},
- $biblioitem->{'collectionvolume'},$biblioitem->{'editionstatement'},
- $biblioitem->{'editionresponsibility'}
- );
- $sth->finish;
- return ($bibitemnum);
-}
-
-=head2 _koha_new_items
-
-=over 4
-
-_koha_new_items( $dbh, $item, $barcode );
-
-=back
-
-=cut
-
-sub _koha_new_items {
- my ( $dbh, $item, $barcode ) = @_;
-
- # my $dbh = C4Connect;
- my $sth = $dbh->prepare("Select max(itemnumber) from items");
- my $data;
- my $itemnumber;
- my $error = "";
-
- $sth->execute;
- $data = $sth->fetchrow_hashref;
- $itemnumber = $data->{'max(itemnumber)'} + 1;
- $sth->finish;
-## Now calculate lccalnumber
- my ($cutterextra) = itemcalculator(
- $dbh,
- $item->{'biblioitemnumber'},
- $item->{'itemcallnumber'}
- );
-
-# FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
- if ( $item->{'loan'} ) {
- $item->{'notforloan'} = $item->{'loan'};
- }
-
- # if dateaccessioned is provided, use it. Otherwise, set to NOW()
- if ( $item->{'dateaccessioned'} eq '' || !$item->{'dateaccessioned'} ) {
-
- $sth = $dbh->prepare(
- "Insert into items set
- itemnumber = ?, biblionumber = ?,
- biblioitemnumber = ?, barcode = ?,
- booksellerid = ?, dateaccessioned = NOW(),
- homebranch = ?, holdingbranch = ?,
- price = ?, replacementprice = ?,
- replacementpricedate = NOW(), datelastseen = NOW(),
- stack = ?,
- itemlost = ?, wthdrawn = ?,
- paidfor = ?, itemnotes = ?,
- itemcallnumber =?, notforloan = ?,
- location = ?, Cutterextra = ?
- "
- );
- $sth->execute(
- $itemnumber, $item->{'biblionumber'},
- $item->{'biblioitemnumber'},
- $barcode, $item->{'booksellerid'},
- $item->{'homebranch'}, $item->{'holdingbranch'},
- $item->{'price'}, $item->{'replacementprice'},
- $item->{stack},
- $item->{itemlost}, $item->{wthdrawn},
- $item->{paidfor}, $item->{'itemnotes'},
- $item->{'itemcallnumber'}, $item->{'notforloan'},
- $item->{'location'}, $cutterextra
- );
- }
- else {
- $sth = $dbh->prepare(
- "INSERT INTO items SET
- itemnumber = ?, biblionumber = ?,
- biblioitemnumber = ?, barcode = ?,
- booksellerid = ?, dateaccessioned = ?,
- homebranch = ?, holdingbranch = ?,
- price = ?, replacementprice = ?,
- replacementpricedate = NOW(), datelastseen = NOW(),
- stack = ?,
- itemlost = ?, wthdrawn = ?,
- paidfor = ?, itemnotes = ?,
- itemcallnumber = ?, notforloan = ?,
- location = ?,
- Cutterextra = ?
- "
- );
- $sth->execute(
- $itemnumber, $item->{'biblionumber'},
- $item->{'biblioitemnumber'},
- $barcode, $item->{'booksellerid'},
- $item->{'dateaccessioned'}, $item->{'homebranch'},
- $item->{'holdingbranch'}, $item->{'price'},
- $item->{'replacementprice'},
- $item->{stack}, $item->{itemlost},
- $item->{wthdrawn}, $item->{paidfor},
- $item->{'itemnotes'}, $item->{'itemcallnumber'},
- $item->{'notforloan'}, $item->{'location'},
- $cutterextra
- );
- }
- if ( defined $sth->errstr ) {
- $error .= $sth->errstr;
- }
- return ( $itemnumber, $error );
-}
-
-=head2 _koha_modify_item
-
-=over 4
-
-_koha_modify_item( $dbh, $item, $op );
-
-=back
-
-=cut
-
-sub _koha_modify_item {
- my ( $dbh, $item, $op ) = @_;
- $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
-
- # if all we're doing is setting statuses, just update those and get out
- if ( $op eq "setstatus" ) {
- my $query =
- "UPDATE items SET itemlost=?,wthdrawn=? WHERE itemnumber=?";
- my @bind = (
- $item->{'itemlost'}, $item->{'wthdrawn'},
- $item->{'itemnumber'}
- );
- my $sth = $dbh->prepare($query);
- $sth->execute(@bind);
- $sth->finish;
- return undef;
- }
-## Now calculate lccalnumber
- my ($cutterextra) =
- itemcalculator( $dbh, $item->{'bibitemnum'}, $item->{'itemcallnumber'} );
-
- my $query = "UPDATE items SET
-barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,stack=?,wthdrawn=?,holdingbranch=?,homebranch=?,cutterextra=?, onloan=?";
-
- my @bind = (
- $item->{'barcode'}, $item->{'notes'},
- $item->{'itemcallnumber'}, $item->{'notforloan'},
- $item->{'location'}, $item->{stack},
- $item->{wthdrawn}, $item->{holdingbranch},
- $item->{homebranch}, $cutterextra,
- $item->{onloan},
+ $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->{'biblioitems.cn_source'},
+ $biblioitem->{'cn_class'},
+ $biblioitem->{'cn_item'},
+ $biblioitem->{'cn_suffix'},
+ $cn_sort,
+ $biblioitem->{'totalissues'}
);
- if ( $item->{'lost'} ne '' ) {
- $query =
-"update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
- itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
- location=?,stack=?,wthdrawn=?,holdingbranch=?,cutterextra=?,onloan=?";
- @bind = (
- $item->{'bibitemnum'}, $item->{'barcode'},
- $item->{'notes'}, $item->{'homebranch'},
- $item->{'lost'}, $item->{'wthdrawn'},
- $item->{'itemcallnumber'}, $item->{'notforloan'},
- $item->{'location'}, $item->{stack},
- $item->{wthdrawn}, $item->{holdingbranch},
- $cutterextra, $item->{onloan}
- );
- if ( $item->{homebranch} ) {
- $query .= ",homebranch=?";
- push @bind, $item->{homebranch};
- }
- if ( $item->{holdingbranch} ) {
- $query .= ",holdingbranch=?";
- push @bind, $item->{holdingbranch};
- }
- }
- $query .= " where itemnumber=?";
- push @bind, $item->{'itemnum'};
- if ( $item->{'replacement'} ne '' ) {
- $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
+ my $bibitemnum = $dbh->{'mysql_insertid'};
+ if ( $dbh->errstr ) {
+ $error.="ERROR in _koha_add_biblioitem $query".$dbh->errstr;
+ warn $error;
}
- my $sth = $dbh->prepare($query);
- $sth->execute(@bind);
- $sth->finish;
+ $sth->finish();
+ return ($bibitemnum,$error);
}
=head2 _koha_delete_biblio
return undef;
}
-=head2 _koha_delete_item
-
-=over 4
-
-_koha_delete_item( $dbh, $itemnum );
-
-Internal function to delete an item record from the koha tables
-
-=back
-
-=cut
-
-sub _koha_delete_item {
- my ( $dbh, $itemnum ) = @_;
-
- my $sth = $dbh->prepare("select * from items where itemnumber=?");
- $sth->execute($itemnum);
- my $data = $sth->fetchrow_hashref;
- $sth->finish;
- my $query = "Insert into deleteditems set ";
- my @bind = ();
- foreach my $temp ( keys %$data ) {
- $query .= "$temp = ?,";
- push( @bind, $data->{$temp} );
- }
- $query =~ s/\,$//;
-
- # print $query;
- $sth = $dbh->prepare($query);
- $sth->execute(@bind);
- $sth->finish;
- $sth = $dbh->prepare("Delete from items where itemnumber=?");
- $sth->execute($itemnum);
- $sth->finish;
-}
-
=head1 UNEXPORTED FUNCTIONS
-=over 4
-
-=head2 calculatelc
-
-$lc = calculatelc($classification);
-
-=back
-
-=cut
-
-sub calculatelc {
- my ($classification) = @_;
- $classification =~ s/^\s+|\s+$//g;
- my $i = 0;
- my $lc2;
- my $lc1;
-
- for ( $i = 0 ; $i < length($classification) ; $i++ ) {
- my $c = ( substr( $classification, $i, 1 ) );
- if ( $c ge '0' && $c le '9' ) {
-
- $lc2 = substr( $classification, $i );
- last;
- }
- else {
- $lc1 .= substr( $classification, $i, 1 );
-
- }
- } #while
-
- my $other = length($lc1);
- if ( !$lc1 ) {
- $other = 0;
- }
-
- my $extras;
- if ( $other < 4 ) {
- for ( 1 .. ( 4 - $other ) ) {
- $extras .= "0";
- }
- }
- $lc1 .= $extras;
- $lc2 =~ s/^ //g;
-
- $lc2 =~ s/ //g;
- $extras = "";
- ##Find the decimal part of $lc2
- my $pos = index( $lc2, "." );
- if ( $pos < 0 ) { $pos = length($lc2); }
- if ( $pos >= 0 && $pos < 5 ) {
- ##Pad lc2 with zeros to create a 5digit decimal needed in marc record to sort as numeric
-
- for ( 1 .. ( 5 - $pos ) ) {
- $extras .= "0";
- }
- }
- $lc2 = $extras . $lc2;
- return ( $lc1 . $lc2 );
-}
-
-=head2 itemcalculator
-
-=over 4
-
-$cutterextra = itemcalculator( $dbh, $biblioitem, $callnumber );
-
-=back
-
-=cut
-
-sub itemcalculator {
- my ( $dbh, $biblioitem, $callnumber ) = @_;
- my $sth =
- $dbh->prepare(
-"select classification, subclass from biblioitems where biblioitemnumber=?"
- );
-
- $sth->execute($biblioitem);
- my ( $classification, $subclass ) = $sth->fetchrow;
- my $all = $classification . " " . $subclass;
- my $total = length($all);
- my $cutterextra = substr( $callnumber, $total - 1 );
-
- return $cutterextra;
-}
-
=head2 ModBiblioMarc
&ModBiblioMarc($newrec,$biblionumber,$frameworkcode);
ModZebra($biblionumber,"specialUpdate","biblioserver",$record);
$sth =
$dbh->prepare(
- "update biblioitems set marc=?,marcxml=? where biblionumber=?");
+ "UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
$sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding),
$biblionumber );
$sth->finish;
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);
return $serviceOptions;
}
-=head2 GetItemsCount
-
-$count = &GetItemsCount( $biblionumber);
-this function return count of item with $biblionumber
-=cut
-
-sub GetItemsCount {
- my ( $biblionumber ) = @_;
- my $dbh = C4::Context->dbh;
- my $query = qq|SELECT count(*)
- FROM items
- WHERE biblionumber=?|;
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber);
- my $count = $sth->fetchrow;
- $sth->finish;
- return ($count);
-}
-
-END { } # module clean-up code here (global destructor)
-
1;
__END__
Joshua Ferraro jmf@liblime.com
=cut
-
-# $Id$
-# $Log$
-# Revision 1.221 2007/07/31 16:01:11 toins
-# Some new functions.
-# TransformHTMLtoMarc rewrited.
-#
-# Revision 1.220 2007/07/20 15:43:16 hdl
-# Bug Fixing GetMarcSubjects.
-# Links parameters were mixed.
-#
-# Revision 1.218 2007/07/19 07:40:08 hdl
-# Adding selection by location for inventory
-#
-# Revision 1.217 2007/07/03 13:47:44 tipaul
-# fixing some display bugs (itemtype not properly returned and a html table bug that makes items appear strangely
-#
-# Revision 1.216 2007/07/03 09:40:58 tipaul
-# return itemtype description properly
-#
-# Revision 1.215 2007/07/03 09:33:05 tipaul
-# if you just replace su by a space in subjects, you'll replace jesus by je s, which is strange for users. this fix solves the problem and introduces authoritysep systempref as separator of subfields, for a better identification of where the authority starts and end
-#
-# Revision 1.214 2007/07/02 09:13:22 tipaul
-# unimarc bugfix : the encoding is in field 100 in UNIMARC. when TransformHTMLtoXML on an item, you must not automatically add a 100 field in items, otherwise there will be 2 100 fields in the biblio, which is wrong
-#
-# Revision 1.213 2007/06/25 15:01:45 tipaul
-# bugfixes on unimarc 100 handling (the field used for encoding)
-#
-# Revision 1.212 2007/06/15 13:44:44 tipaul
-# some fixes (and only fixes)
-#
-# Revision 1.211 2007/06/15 09:40:06 toins
-# do not get $3 $4 and $5 on GetMarcSubjects GetMarcAuthors on unimarc flavour.
-#
-# Revision 1.210 2007/06/13 13:03:34 toins
-# removing warn compilation.
-#
-# Revision 1.209 2007/05/23 16:19:40 tipaul
-# various bugfixes (minor) and french translation updated
-#
-# Revision 1.208 2007/05/22 09:13:54 tipaul
-# Bugfixes & improvements (various and minor) :
-# - updating templates to have tmpl_process3.pl running without any errors
-# - adding a drupal-like css for prog templates (with 3 small images)
-# - fixing some bugs in circulation & other scripts
-# - updating french translation
-# - fixing some typos in templates
-#
-# Revision 1.207 2007/05/22 08:51:19 hdl
-# Changing GetMarcStructure signature.
-# Deleting first parameter $dbh
-#
-# Revision 1.206 2007/05/21 08:44:17 btoumi
-# add security when u delete biblio :
-# u must delete linked items before delete biblio
-#
-# Revision 1.205 2007/05/11 16:04:03 btoumi
-# bug fix:
-# problem in displayed label link with subject in detail.tmpl
-# ex: label random => rdom
-#
-# Revision 1.204 2007/05/10 14:45:15 tipaul
-# Koha NoZebra :
-# - support for authorities
-# - some bugfixes in ordering and "CCL" parsing
-# - support for authorities <=> biblios walking
-#
-# Seems I can do what I want now, so I consider its done, except for bugfixes that will be needed i m sure !
-#
-# Revision 1.203 2007/05/03 15:16:02 tipaul
-# BUGFIX for : NoZebra
-# - NoZebra features : seems they work fine now (adding, modifying, deleting)
-# - Biblio edition major bugfix : before this commit editing a biblio resulted in an item removal in marcxml field
-#
-# Revision 1.202 2007/05/02 16:44:31 tipaul
-# NoZebra SQL index management :
-# * adding 3 subs in Biblio.pm
-# - GetNoZebraIndexes, that get the index structure in a new systempreference (added with this commit)
-# - _DelBiblioNoZebra, that retrieve all index entries for a biblio and remove in a variable the biblio reference
-# - _AddBiblioNoZebra, that add index entries for a biblio.
-# Note that the 2 _Add and _Del subs work only in a hash variable, to speed up things in case of a modif (ie : delete+add). The effective SQL update is done in the ModZebra sub (that existed before, and dealed with zebra index).
-# I think the code has to be more deeply tested, but it works at least partially.
-#
-# Revision 1.201 2007/04/27 14:00:49 hdl
-# Removing $dbh from GetMarcFromKohaField (dbh is not used in this function.)
-#
-# Revision 1.200 2007/04/25 16:26:42 tipaul
-# Koha 3.0 nozebra 1st commit : the script misc/migration_tools/rebuild_nozebra.pl build the nozebra table, and, if you set NoZebra to Yes, queries will be done through zebra. TODO :
-# - add nozebra table management on biblio editing
-# - the index table content is hardcoded. I still have to add some specific systempref to let the library update it
-# - manage pagination (next/previous)
-# - manage facets
-# WHAT works :
-# - NZgetRecords : has exactly the same API & returns as zebra getQuery, except that some parameters are unused
-# - search & sort works quite good
-# - CQL parser is better that what I thought I could do : title="harry and sally" and publicationyear>2000 not itemtype=LIVR should work fine
-#
-# Revision 1.199 2007/04/24 09:07:53 tipaul
-# moving dotransfer to Biblio.pm::ModItemTransfer + some CheckReserves fixes
-#
-# Revision 1.198 2007/04/23 15:21:17 tipaul
-# renaming currenttransfers to transferstoreceive
-#
-# Revision 1.197 2007/04/18 17:00:14 tipaul
-# removing all useless %env / $env
-#
-# Revision 1.196 2007/04/17 08:48:00 tipaul
-# circulation cleaning continued: bufixing
-#
-# Revision 1.195 2007/04/04 16:46:22 tipaul
-# HUGE COMMIT : code cleaning circulation.
-#
-# some stuff to do, i'll write a mail on koha-devel NOW !
-#
-# Revision 1.194 2007/03/30 12:00:42 tipaul
-# why the hell do we need to explicitly utf8 decode this string ? I really don't know, but it seems it's mandatory, otherwise, tag descriptions are not properly encoded...
-#
-# Revision 1.193 2007/03/29 16:45:53 tipaul
-# Code cleaning of Biblio.pm (continued)
-#
-# All subs have be cleaned :
-# - removed useless
-# - merged some
-# - reordering Biblio.pm completly
-# - using only naming conventions
-#
-# Seems to have broken nothing, but it still has to be heavily tested.
-# Note that Biblio.pm is now much more efficient than previously & probably more reliable as well.
-#
-# Revision 1.192 2007/03/29 13:30:31 tipaul
-# Code cleaning :
-# == Biblio.pm cleaning (useless) ==
-# * some sub declaration dropped
-# * removed modbiblio sub
-# * removed moditem sub
-# * removed newitems. It was used only in finishrecieve. Replaced by a TransformKohaToMarc+AddItem, that is better.
-# * removed MARCkoha2marcItem
-# * removed MARCdelsubfield declaration
-# * removed MARCkoha2marcBiblio
-#
-# == Biblio.pm cleaning (naming conventions) ==
-# * MARCgettagslib renamed to GetMarcStructure
-# * MARCgetitems renamed to GetMarcItem
-# * MARCfind_frameworkcode renamed to GetFrameworkCode
-# * MARCmarc2koha renamed to TransformMarcToKoha
-# * MARChtml2marc renamed to TransformHtmlToMarc
-# * MARChtml2xml renamed to TranformeHtmlToXml
-# * zebraop renamed to ModZebra
-#
-# == MARC=OFF ==
-# * removing MARC=OFF related scripts (in cataloguing directory)
-# * removed checkitems (function related to MARC=off feature, that is completly broken in head. If someone want to reintroduce it, hard work coming...)
-# * removed getitemsbybiblioitem (used only by MARC=OFF scripts, that is removed as well)
-#
-# Revision 1.191 2007/03/29 09:42:13 tipaul
-# adding default value new feature into cataloguing. The system (definition) part has already been added by toins
-#
-# Revision 1.190 2007/03/29 08:45:19 hdl
-# Deleting ignore_errors(1) pour MARC::Charset
-#
-# Revision 1.189 2007/03/28 10:39:16 hdl
-# removing $dbh as a parameter in AuthoritiesMarc functions
-# And reporting all differences into the scripts taht relies on those functions.