use strict;
#use warnings; FIXME - Bug 2505
-use Carp;
-use C4::Context;
-use C4::Koha;
-use C4::Biblio;
-use Koha::DateUtils;
-use MARC::Record;
-use C4::ClassSource;
-use C4::Log;
-use List::MoreUtils qw/any/;
-use YAML qw/Load/;
-use DateTime::Format::MySQL;
-use Data::Dumper; # used as part of logging item record changes, not just for
- # debugging; so please don't remove this
-use Koha::DateUtils qw/dt_from_string/;
-use Koha::Database;
-
-use Koha::Biblioitems;
-use Koha::Items;
-use Koha::SearchEngine;
-use Koha::SearchEngine::Search;
-use Koha::Libraries;
-
use vars qw(@ISA @EXPORT);
-
BEGIN {
+ require Exporter;
+ @ISA = qw(Exporter);
- require Exporter;
- @ISA = qw( Exporter );
-
- # function exports
@EXPORT = qw(
GetItem
AddItemFromMarc
AddItem
AddItemBatchFromMarc
ModItemFromMarc
- Item2Marc
+ Item2Marc
ModItem
ModDateLastSeen
ModItemTransfer
DelItem
-
CheckItemPreSave
-
- GetItemStatus
- GetItemLocation
- GetLostItems
GetItemsForInventory
- GetItemsCount
- GetItemInfosOf
- GetItemsByBiblioitemnumber
GetItemsInfo
- GetItemsLocationInfo
- GetHostItemsInfo
- GetItemnumbersForBiblio
- get_itemnumbers_of
- get_hostitemnumbers_of
- GetItemnumberFromBarcode
- GetBarcodeFromItemnumber
+ GetItemsLocationInfo
+ GetHostItemsInfo
+ get_hostitemnumbers_of
GetHiddenItemnumbers
ItemSafeToDelete
DelItemCheck
- MoveItemFromBiblio
- GetLatestAcquisitions
-
+ MoveItemFromBiblio
CartToShelf
ShelfToCart
-
- GetAnalyticsCount
- GetItemHolds
-
+ GetAnalyticsCount
SearchItemsByField
SearchItems
-
PrepareItemrecordDisplay
-
);
}
+use Carp;
+use C4::Context;
+use C4::Koha;
+use C4::Biblio;
+use Koha::DateUtils;
+use MARC::Record;
+use C4::ClassSource;
+use C4::Log;
+use List::MoreUtils qw(any);
+use YAML qw(Load);
+use DateTime::Format::MySQL;
+use Data::Dumper; # used as part of logging item record changes, not just for
+ # debugging; so please don't remove this
+
+use Koha::AuthorisedValues;
+use Koha::DateUtils qw(dt_from_string);
+use Koha::Database;
+
+use Koha::Biblioitems;
+use Koha::Items;
+use Koha::ItemTypes;
+use Koha::SearchEngine;
+use Koha::SearchEngine::Search;
+use Koha::Libraries;
+
=head1 NAME
C4::Items - item management functions
records in Koha, and is used by cataloguing, circulation,
acquisitions, and serials management.
+# FIXME This POD is not up-to-date
A Koha item record is stored in two places: the
items table and embedded in a MARC tag in the XML
version of the associated bib record in C<biblioitems.marcxml>.
sub GetItem {
my ($itemnumber,$barcode, $serial) = @_;
my $dbh = C4::Context->dbh;
- my $data;
+ my $item;
if ($itemnumber) {
- my $sth = $dbh->prepare("
- SELECT * FROM items
- WHERE itemnumber = ?");
- $sth->execute($itemnumber);
- $data = $sth->fetchrow_hashref;
+ $item = Koha::Items->find( $itemnumber );
} else {
- my $sth = $dbh->prepare("
- SELECT * FROM items
- WHERE barcode = ?"
- );
- $sth->execute($barcode);
- $data = $sth->fetchrow_hashref;
- }
-
- return unless ( $data );
-
- if ( $serial) {
- my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=?");
- $ssth->execute($data->{'itemnumber'}) ;
- ($data->{'serialseq'} , $data->{'publisheddate'}) = $ssth->fetchrow_array();
- }
- #if we don't have an items.itype, use biblioitems.itemtype.
- # FIXME this should respect the itypes systempreference
- # if (C4::Context->preference('item-level_itypes')) {
- if( ! $data->{'itype'} ) {
- my $sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?");
- $sth->execute($data->{'biblionumber'});
- ($data->{'itype'}) = $sth->fetchrow_array;
- }
+ $item = Koha::Items->find( { barcode => $barcode } );
+ }
+
+ return unless ( $item );
+
+ my $data = $item->unblessed();
+ $data->{itype} = $item->effective_itemtype(); # set the correct itype
+
+ if ($serial) {
+ my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=?");
+ $ssth->execute( $data->{'itemnumber'} );
+ ( $data->{'serialseq'}, $data->{'publisheddate'} ) = $ssth->fetchrow_array();
+ }
+
return $data;
} # sub GetItem
my $dbh = C4::Context->dbh;
# parse item hash from MARC
- my $frameworkcode = GetFrameworkCode( $biblionumber );
- my ($itemtag,$itemsubfield)=GetMarcFromKohaField("items.itemnumber",$frameworkcode);
-
- my $localitemmarc=MARC::Record->new;
- $localitemmarc->append_fields($source_item_marc->field($itemtag));
- my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode ,'items');
- my $unlinked_item_subfields = _get_unlinked_item_subfields($localitemmarc, $frameworkcode);
- return AddItem($item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields);
+ my $frameworkcode = C4::Biblio::GetFrameworkCode($biblionumber);
+ my ( $itemtag, $itemsubfield ) = C4::Biblio::GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+
+ my $localitemmarc = MARC::Record->new;
+ $localitemmarc->append_fields( $source_item_marc->field($itemtag) );
+ my $item = C4::Biblio::TransformMarcToKoha( $localitemmarc, $frameworkcode, 'items' );
+ my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
+ return AddItem( $item, $biblionumber, $dbh, $frameworkcode, $unlinked_item_subfields );
}
=head2 AddItem
=cut
sub AddItem {
- my $item = shift;
+ my $item = shift;
my $biblionumber = shift;
my $dbh = @_ ? shift : C4::Context->dbh;
- my $frameworkcode = @_ ? shift : GetFrameworkCode( $biblionumber );
- my $unlinked_item_subfields;
+ my $frameworkcode = @_ ? shift : C4::Biblio::GetFrameworkCode($biblionumber);
+ my $unlinked_item_subfields;
if (@_) {
- $unlinked_item_subfields = shift
- };
+ $unlinked_item_subfields = shift;
+ }
# needs old biblionumber and biblioitemnumber
$item->{'biblionumber'} = $biblionumber;
my $sth = $dbh->prepare("SELECT biblioitemnumber FROM biblioitems WHERE biblionumber=?");
$sth->execute( $item->{'biblionumber'} );
- ($item->{'biblioitemnumber'}) = $sth->fetchrow;
+ ( $item->{'biblioitemnumber'} ) = $sth->fetchrow;
_set_defaults_for_add($item);
_set_derived_columns_for_add($item);
$item->{'more_subfields_xml'} = _get_unlinked_subfields_xml($unlinked_item_subfields);
+
# FIXME - checks here
- unless ( $item->{itype} ) { # default to biblioitem.itemtype if no itype
+ unless ( $item->{itype} ) { # default to biblioitem.itemtype if no itype
my $itype_sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?");
$itype_sth->execute( $item->{'biblionumber'} );
( $item->{'itype'} ) = $itype_sth->fetchrow_array;
}
- my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
+ my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
+ return if $error;
+
$item->{'itemnumber'} = $itemnumber;
- ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver" );
-
- logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
-
- return ($item->{biblionumber}, $item->{biblioitemnumber}, $itemnumber);
+ C4::Biblio::ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver" );
+
+ logaction( "CATALOGUING", "ADD", $itemnumber, "item" )
+ if C4::Context->preference("CataloguingLog");
+
+ return ( $item->{biblionumber}, $item->{biblioitemnumber}, $itemnumber );
}
=head2 AddItemBatchFromMarc
This API assumes that the bib record has already been
saved to the C<biblio> and C<biblioitems> tables. It does
-not expect that C<biblioitems.marc> and C<biblioitems.marcxml>
-are populated, but it will do so via a call to ModBibiloMarc.
+not expect that C<biblio_metadata.metadata> is populated, but it
+will do so via a call to ModBibiloMarc.
The goal of this API is to have a similar effect to using AddBiblio
and AddItems in succession, but without inefficient repeated
$record = $record->clone();
# loop through the item tags and start creating items
my @bad_item_fields = ();
- my ($itemtag, $itemsubfield) = &GetMarcFromKohaField("items.itemnumber",'');
+ my ($itemtag, $itemsubfield) = C4::Biblio::GetMarcFromKohaField("items.itemnumber",'');
my $item_sequence_num = 0;
ITEMFIELD: foreach my $item_field ($record->field($itemtag)) {
$item_sequence_num++;
=cut
sub _build_default_values_for_mod_marc {
- my ($frameworkcode) = @_;
+ # Has no framework parameter anymore, since Default is authoritative
+ # for Koha to MARC mappings.
my $cache = Koha::Caches->get_instance();
- my $cache_key = "default_value_for_mod_marc-$frameworkcode";
+ my $cache_key = "default_value_for_mod_marc-";
my $cached = $cache->get_from_cache($cache_key);
return $cached if $cached;
while ( my ( $field, $default_value ) = each %$default_values ) {
my $kohafield = $field;
$kohafield =~ s|^([^\.]+)$|items.$1|;
- $default_values_for_mod_from_marc{$field} =
- $default_value
- if C4::Koha::IsKohaFieldLinked(
- { kohafield => $kohafield, frameworkcode => $frameworkcode } );
+ $default_values_for_mod_from_marc{$field} = $default_value
+ if C4::Biblio::GetMarcFromKohaField( $kohafield );
}
$cache->set_in_cache($cache_key, \%default_values_for_mod_from_marc);
my $biblionumber = shift;
my $itemnumber = shift;
- my $dbh = C4::Context->dbh;
- my $frameworkcode = GetFrameworkCode($biblionumber);
- my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+ my $frameworkcode = C4::Biblio::GetFrameworkCode($biblionumber);
+ my ( $itemtag, $itemsubfield ) = C4::Biblio::GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
my $localitemmarc = MARC::Record->new;
$localitemmarc->append_fields( $item_marc->field($itemtag) );
- my $item = &TransformMarcToKoha( $localitemmarc, $frameworkcode, 'items' );
- my $default_values = _build_default_values_for_mod_marc($frameworkcode);
+ my $item = TransformMarcToKoha( $localitemmarc, $frameworkcode, 'items' );
+ my $default_values = _build_default_values_for_mod_marc();
foreach my $item_field ( keys %$default_values ) {
$item->{$item_field} = $default_values->{$item_field}
unless exists $item->{$item_field};
}
my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
- ModItem($item, $biblionumber, $itemnumber, $dbh, $frameworkcode, $unlinked_item_subfields);
+ ModItem( $item, $biblionumber, $itemnumber, { unlinked_item_subfields => $unlinked_item_subfields } );
return $item;
}
=head2 ModItem
- ModItem({ column => $newvalue }, $biblionumber, $itemnumber);
+ModItem(
+ { column => $newvalue },
+ $biblionumber,
+ $itemnumber,
+ {
+ [ unlinked_item_subfields => $unlinked_item_subfields, ]
+ [ log_action => 1, ]
+ }
+);
-Change one or more columns in an item record and update
-the MARC representation of the item.
+Change one or more columns in an item record.
The first argument is a hashref mapping from item column
names to the new values. The second and third arguments
are the biblionumber and itemnumber, respectively.
+The fourth, optional parameter (additional_params) may contain the keys
+unlinked_item_subfields and log_action.
-The fourth, optional parameter, C<$unlinked_item_subfields>, contains
-an arrayref containing subfields present in the original MARC
+C<$unlinked_item_subfields> contains an arrayref containing
+subfields present in the original MARC
representation of the item (e.g., from the item editor) that are
not mapped to C<items> columns directly but should instead
be stored in C<items.more_subfields_xml> and included in
this routine will perform the necessary calculation
and set the value.
+If log_action is set to false, the action will not be logged.
+If log_action is true or undefined, the action will be logged.
+
=cut
sub ModItem {
- my $item = shift;
- my $biblionumber = shift;
- my $itemnumber = shift;
+ my ( $item, $biblionumber, $itemnumber, $additional_params ) = @_;
+ my $log_action = $additional_params->{log_action} // 1;
+ my $unlinked_item_subfields = $additional_params->{unlinked_item_subfields};
+
+ return unless %$item;
+ $item->{'itemnumber'} = $itemnumber or return;
# if $biblionumber is undefined, get it from the current item
unless (defined $biblionumber) {
$biblionumber = _get_single_item_column('biblionumber', $itemnumber);
}
- my $dbh = @_ ? shift : C4::Context->dbh;
- my $frameworkcode = @_ ? shift : GetFrameworkCode( $biblionumber );
-
- my $unlinked_item_subfields;
- if (@_) {
- $unlinked_item_subfields = shift;
+ if ($unlinked_item_subfields) {
$item->{'more_subfields_xml'} = _get_unlinked_subfields_xml($unlinked_item_subfields);
};
- $item->{'itemnumber'} = $itemnumber or return;
-
- my @fields = qw( itemlost withdrawn );
+ my @fields = qw( itemlost withdrawn damaged );
# Only call GetItem if we need to set an "on" date field
- if ( $item->{itemlost} || $item->{withdrawn} ) {
+ if ( $item->{itemlost} || $item->{withdrawn} || $item->{damaged} ) {
my $pre_mod_item = GetItem( $item->{'itemnumber'} );
for my $field (@fields) {
if ( defined( $item->{$field} )
# item status is possible
ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
- logaction("CATALOGUING", "MODIFY", $itemnumber, "item ".Dumper($item)) if C4::Context->preference("CataloguingLog");
+ logaction( "CATALOGUING", "MODIFY", $itemnumber, "item " . Dumper($item) )
+ if $log_action && C4::Context->preference("CataloguingLog");
}
=head2 ModItemTransfer
# Remove the 'shelving cart' location status if it is being used.
CartToShelf( $itemnumber ) if ( C4::Context->preference("ReturnToShelvingCart") );
+ $dbh->do("UPDATE branchtransfers SET datearrived = NOW(), comments = ? WHERE itemnumber = ? AND datearrived IS NULL", undef, "Canceled, new transfer from $frombranch to $tobranch created", $itemnumber);
+
#new entry in branchtransfers....
my $sth = $dbh->prepare(
"INSERT INTO branchtransfers (itemnumber, frombranch, datesent, tobranch)
VALUES (?, ?, NOW(), ?)");
$sth->execute($itemnumber, $frombranch, $tobranch);
- ModItem({ holdingbranch => $tobranch }, undef, $itemnumber);
+ ModItem({ holdingbranch => $tobranch }, undef, $itemnumber, { log_action => 0 });
ModDateLastSeen($itemnumber);
return;
}
=head2 ModDateLastSeen
- ModDateLastSeen($itemnum);
+ModDateLastSeen( $itemnumber, $leave_item_lost );
Mark item as seen. Is called when an item is issued, returned or manually marked during inventory/stocktaking.
-C<$itemnum> is the item number
+C<$itemnumber> is the item number
+C<$leave_item_lost> determines if a lost item will be found or remain lost
=cut
sub ModDateLastSeen {
- my ($itemnumber) = @_;
-
+ my ( $itemnumber, $leave_item_lost ) = @_;
+
my $today = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
- ModItem({ itemlost => 0, datelastseen => $today }, undef, $itemnumber);
+
+ my $params;
+ $params->{datelastseen} = $today;
+ $params->{itemlost} = 0 unless $leave_item_lost;
+
+ ModItem( $params, undef, $itemnumber, { log_action => 0 } );
}
=head2 DelItem
my $biblionumber = $params->{biblionumber};
unless ($biblionumber) {
- $biblionumber = C4::Biblio::GetBiblionumberFromItemnumber($itemnumber);
+ my $item = Koha::Items->find( $itemnumber );
+ $biblionumber = $item ? $item->biblio->biblionumber : undef;
}
# If there is no biblionumber for the given itemnumber, there is nothing to delete
# FIXME check the item has no current issues
my $deleted = _koha_delete_item( $itemnumber );
- # get the MARC record
- my $record = GetMarcBiblio($biblionumber);
ModZebra( $biblionumber, "specialUpdate", "biblioserver" );
#search item field code
# check for duplicate barcode
if (exists $item_ref->{'barcode'} and defined $item_ref->{'barcode'}) {
- my $existing_itemnumber = GetItemnumberFromBarcode($item_ref->{'barcode'});
- if ($existing_itemnumber) {
+ my $existing_item= Koha::Items->find({barcode => $item_ref->{'barcode'}});
+ if ($existing_item) {
if (!exists $item_ref->{'itemnumber'} # new item
- or $item_ref->{'itemnumber'} != $existing_itemnumber) { # existing item
+ or $item_ref->{'itemnumber'} != $existing_item->itemnumber) { # existing item
$errors{'duplicate_barcode'} = $item_ref->{'barcode'};
}
}
getting an item record, a set of item records, or
lists of authorized values for certain item fields.
-Some of the functions in this group are candidates
-for refactoring -- for example, some of the code
-in C<GetItemsByBiblioitemnumber> and C<GetItemsInfo>
-has copy-and-paste work.
-
-=cut
-
-=head2 GetItemStatus
-
- $itemstatushash = GetItemStatus($fwkcode);
-
-Returns a list of valid values for the
-C<items.notforloan> field.
-
-NOTE: does B<not> return an individual item's
-status.
-
-Can be MARC dependent.
-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" id="statusloop">
- <option value="">Default</option>
- [% FOREACH statusloo IN statusloop %]
- [% IF ( statusloo.selected ) %]
- <option value="[% statusloo.value %]" selected="selected">[% statusloo.statusname %]</option>
- [% ELSE %]
- <option value="[% statusloo.value %]">[% statusloo.statusname %]</option>
- [% END %]
- [% END %]
-</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;
- }
- return \%itemstatus;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- }
-
- #No authvalue list
- #build default
- $itemstatus{"1"} = "Not For Loan";
- return \%itemstatus;
-}
-
-=head2 GetItemLocation
-
- $itemlochash = GetItemLocation($fwk);
-
-Returns a list of valid values for the
-C<items.location> field.
-
-NOTE: does B<not> return an individual item's
-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>
-
-=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;
- }
- return \%itemlocation;
- exit 1;
- }
- else {
-
- #No authvalue list
- # build default
- }
- }
-
- #No authvalue list
- #build default
- $itemlocation{"1"} = "Not For Loan";
- return \%itemlocation;
-}
-
-=head2 GetLostItems
-
- $items = GetLostItems( $where );
-
-This function gets a list of lost 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. For example:
-
-{ barcode => 'abc123',
- homebranch => 'CPL', }
-
-=item return:
-
-C<$items> is a reference to an array full of hashrefs with columns
-from the "items" table as keys.
-
-=item usage in the perl script:
-
- my $where = { barcode => '0001548' };
- my $items = GetLostItems( $where );
- $template->param( itemsloop => $items );
-
-=back
-
=cut
-sub GetLostItems {
- # Getting input args.
- my $where = shift;
- my $dbh = C4::Context->dbh;
-
- my $query = "
- SELECT title, author, lib, itemlost, authorised_value, barcode, datelastseen, price, replacementprice, homebranch,
- itype, itemtype, holdingbranch, location, itemnotes, items.biblionumber as biblionumber, itemcallnumber
- FROM items
- LEFT JOIN biblio ON (items.biblionumber = biblio.biblionumber)
- LEFT JOIN biblioitems ON (items.biblionumber = biblioitems.biblionumber)
- LEFT JOIN authorised_values ON (items.itemlost = authorised_values.authorised_value)
- WHERE
- authorised_values.category = 'LOST'
- AND itemlost IS NOT NULL
- AND itemlost <> 0
- ";
- my @query_parameters;
- foreach my $key (keys %$where) {
- $query .= " AND $key LIKE ?";
- push @query_parameters, "%$where->{$key}%";
- }
-
- my $sth = $dbh->prepare($query);
- $sth->execute( @query_parameters );
- my $items = [];
- while ( my $row = $sth->fetchrow_hashref ){
- push @$items, $row;
- }
- return $items;
-}
-
=head2 GetItemsForInventory
($itemlist, $iTotalRecords) = GetItemsForInventory( {
offset => $offset,
size => $size,
statushash => $statushash,
- interface => $interface,
} );
Retrieve a list of title/authors/barcode/callnumber, for biblio inventory.
my ( $parameters ) = @_;
my $minlocation = $parameters->{'minlocation'} // '';
my $maxlocation = $parameters->{'maxlocation'} // '';
+ my $class_source = $parameters->{'class_source'} // C4::Context->preference('DefaultClassificationSource');
my $location = $parameters->{'location'} // '';
my $itemtype = $parameters->{'itemtype'} // '';
my $ignoreissued = $parameters->{'ignoreissued'} // '';
my $offset = $parameters->{'offset'} // '';
my $size = $parameters->{'size'} // '';
my $statushash = $parameters->{'statushash'} // '';
- my $interface = $parameters->{'interface'} // '';
+ my $ignore_waiting_holds = $parameters->{'ignore_waiting_holds'} // '';
my $dbh = C4::Context->dbh;
my ( @bind_params, @where_strings );
+ my $min_cnsort = GetClassSort($class_source,undef,$minlocation);
+ my $max_cnsort = GetClassSort($class_source,undef,$maxlocation);
+
my $select_columns = q{
SELECT items.itemnumber, barcode, itemcallnumber, title, author, biblio.biblionumber, biblio.frameworkcode, datelastseen, homebranch, location, notforloan, damaged, itemlost, withdrawn, stocknumber
};
}
if ($minlocation) {
- push @where_strings, 'itemcallnumber >= ?';
- push @bind_params, $minlocation;
+ push @where_strings, 'items.cn_sort >= ?';
+ push @bind_params, $min_cnsort;
}
if ($maxlocation) {
- push @where_strings, 'itemcallnumber <= ?';
- push @bind_params, $maxlocation;
+ push @where_strings, 'items.cn_sort <= ?';
+ push @bind_params, $max_cnsort;
}
if ($datelastseen) {
push @where_strings, 'issues.date_due IS NULL';
}
+ if ( $ignore_waiting_holds ) {
+ $query .= "LEFT JOIN reserves ON items.itemnumber = reserves.itemnumber ";
+ push( @where_strings, q{(reserves.found != 'W' OR reserves.found IS NULL)} );
+ }
+
if ( @where_strings ) {
$query .= 'WHERE ';
$query .= join ' AND ', @where_strings;
}
- $query .= ' ORDER BY items.cn_sort, itemcallnumber, title';
my $count_query = $select_count . $query;
+ $query .= ' ORDER BY items.cn_sort, itemcallnumber, title';
$query .= " LIMIT $offset, $size" if ($offset and $size);
$query = $select_columns . $query;
my $sth = $dbh->prepare($query);
$sth->execute( @bind_params );
my ($iTotalRecords) = $sth->fetchrow_array();
- my $avmapping = C4::Koha::GetKohaAuthorisedValuesMapping( {
- interface => $interface
- } );
+ my @avs = Koha::AuthorisedValues->search(
+ { 'marc_subfield_structures.kohafield' => { '>' => '' },
+ 'me.authorised_value' => { '>' => '' },
+ },
+ { join => { category => 'marc_subfield_structures' },
+ distinct => ['marc_subfield_structures.kohafield, me.category, frameworkcode, me.authorised_value'],
+ '+select' => [ 'marc_subfield_structures.kohafield', 'marc_subfield_structures.frameworkcode', 'me.authorised_value', 'me.lib' ],
+ '+as' => [ 'kohafield', 'frameworkcode', 'authorised_value', 'lib' ],
+ }
+ );
+
+ my $avmapping = { map { $_->get_column('kohafield') . ',' . $_->get_column('frameworkcode') . ',' . $_->get_column('authorised_value') => $_->get_column('lib') } @avs };
+
foreach my $row (@$tmpresults) {
# Auth values
return (\@results, $iTotalRecords);
}
-=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 = "SELECT count(*)
- FROM items
- WHERE biblionumber=?";
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber);
- my $count = $sth->fetchrow;
- return ($count);
-}
-
-=head2 GetItemInfosOf
-
- GetItemInfosOf(@itemnumbers);
-
-=cut
-
-sub GetItemInfosOf {
- my @itemnumbers = @_;
-
- my $itemnumber_values = @itemnumbers ? join( ',', @itemnumbers ) : "''";
-
- my $query = "
- SELECT *
- FROM items
- WHERE itemnumber IN ($itemnumber_values)
- ";
- return get_infos_of( $query, 'itemnumber' );
-}
-
-=head2 GetItemsByBiblioitemnumber
-
- GetItemsByBiblioitemnumber($biblioitemnumber);
-
-Returns an arrayref of hashrefs suitable for use in a TMPL_LOOP
-Called by C<C4::XISBN>
-
-=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 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 withdrawn
- $data->{'date_due'} = '';
- } # else
- # Find the last 3 people who borrowed this item.
- my $query2 = "SELECT * FROM old_issues, borrowers WHERE itemnumber = ?
- AND old_issues.borrowernumber = borrowers.borrowernumber
- 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++;
- }
- push(@results,$data);
- }
- return (\@results);
-}
-
=head2 GetItemsInfo
@results = GetItemsInfo($biblionumber);
sub GetItemsInfo {
my ( $biblionumber ) = @_;
my $dbh = C4::Context->dbh;
- # note biblioitems.* must be avoided to prevent large marc and marcxml fields from killing performance.
require C4::Languages;
my $language = C4::Languages::getlanguage();
my $query = "
$serial ||= $data->{'serial'};
+ my $descriptions;
# get notforloan complete status if applicable
- if ( my $code = C4::Koha::GetAuthValCode( 'items.notforloan', $data->{frameworkcode} ) ) {
- $data->{notforloanvalue} = C4::Koha::GetKohaAuthorisedValueLib( $code, $data->{itemnotforloan} );
- $data->{notforloanvalueopac} = C4::Koha::GetKohaAuthorisedValueLib( $code, $data->{itemnotforloan}, 1 );
- }
+ $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.notforloan', authorised_value => $data->{itemnotforloan} });
+ $data->{notforloanvalue} = $descriptions->{lib} // '';
+ $data->{notforloanvalueopac} = $descriptions->{opac_description} // '';
# get restricted status and description if applicable
- if ( my $code = C4::Koha::GetAuthValCode( 'items.restricted', $data->{frameworkcode} ) ) {
- $data->{restrictedopac} = C4::Koha::GetKohaAuthorisedValueLib( $code, $data->{restricted}, 1 );
- $data->{restricted} = C4::Koha::GetKohaAuthorisedValueLib( $code, $data->{restricted} );
- }
+ $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.restricted', authorised_value => $data->{restricted} });
+ $data->{restricted} = $descriptions->{lib} // '';
+ $data->{restrictedopac} = $descriptions->{opac_description} // '';
# my stack procedures
- if ( my $code = C4::Koha::GetAuthValCode( 'items.stack', $data->{frameworkcode} ) ) {
- $data->{stack} = C4::Koha::GetKohaAuthorisedValueLib( $code, $data->{stack} );
- }
+ $descriptions = Koha::AuthorisedValues->get_description_by_koha_field({frameworkcode => $data->{frameworkcode}, kohafield => 'items.stack', authorised_value => $data->{stack} });
+ $data->{stack} = $descriptions->{lib} // '';
# Find the last 3 people who borrowed this item.
my $sth2 = $dbh->prepare("SELECT * FROM old_issues,borrowers
$sth->execute($biblionumber);
while ( my $data = $sth->fetchrow_hashref ) {
- $data->{location_intranet} = GetKohaAuthorisedValueLib('LOC', $data->{location});
- $data->{location_opac}= GetKohaAuthorisedValueLib('LOC', $data->{location}, 1);
+ my $av = Koha::AuthorisedValues->search({ category => 'LOC', authorised_value => $data->{location} });
+ $av = $av->count ? $av->next : undef;
+ $data->{location_intranet} = $av ? $av->lib : '';
+ $data->{location_opac} = $av ? $av->opac_description : '';
push @results, $data;
}
return @results;
=head2 GetHostItemsInfo
- $hostiteminfo = GetHostItemsInfo($hostfield);
- Returns the iteminfo for items linked to records via a host field
+ $hostiteminfo = GetHostItemsInfo($hostfield);
+ Returns the iteminfo for items linked to records via a host field
=cut
sub GetHostItemsInfo {
- my ($record) = @_;
- my @returnitemsInfo;
-
- if (C4::Context->preference('marcflavour') eq 'MARC21' ||
- C4::Context->preference('marcflavour') eq 'NORMARC'){
- foreach my $hostfield ( $record->field('773') ) {
- my $hostbiblionumber = $hostfield->subfield("0");
- my $linkeditemnumber = $hostfield->subfield("9");
- my @hostitemInfos = GetItemsInfo($hostbiblionumber);
- foreach my $hostitemInfo (@hostitemInfos){
- if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){
- push (@returnitemsInfo,$hostitemInfo);
- last;
- }
- }
- }
- } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC'){
- foreach my $hostfield ( $record->field('461') ) {
- my $hostbiblionumber = $hostfield->subfield("0");
- my $linkeditemnumber = $hostfield->subfield("9");
- my @hostitemInfos = GetItemsInfo($hostbiblionumber);
- foreach my $hostitemInfo (@hostitemInfos){
- if ($hostitemInfo->{itemnumber} eq $linkeditemnumber){
- push (@returnitemsInfo,$hostitemInfo);
- last;
- }
- }
- }
- }
- return @returnitemsInfo;
-}
-
-
-=head2 GetLastAcquisitions
-
- my $lastacq = GetLastAcquisitions({'branches' => ('branch1','branch2'),
- 'itemtypes' => ('BK','BD')}, 10);
-
-=cut
-
-sub GetLastAcquisitions {
- my ($data,$max) = @_;
-
- my $itemtype = C4::Context->preference('item-level_itypes') ? 'itype' : 'itemtype';
-
- my $number_of_branches = @{$data->{branches}};
- my $number_of_itemtypes = @{$data->{itemtypes}};
-
-
- my @where = ('WHERE 1 ');
- $number_of_branches and push @where
- , 'AND holdingbranch IN ('
- , join(',', ('?') x $number_of_branches )
- , ')'
- ;
-
- $number_of_itemtypes and push @where
- , "AND $itemtype IN ("
- , join(',', ('?') x $number_of_itemtypes )
- , ')'
- ;
-
- my $query = "SELECT biblio.biblionumber as biblionumber, title, dateaccessioned
- FROM items RIGHT JOIN biblio ON (items.biblionumber=biblio.biblionumber)
- RIGHT JOIN biblioitems ON (items.biblioitemnumber=biblioitems.biblioitemnumber)
- @where
- GROUP BY biblio.biblionumber
- ORDER BY dateaccessioned DESC LIMIT $max";
-
- my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare($query);
-
- $sth->execute((@{$data->{branches}}, @{$data->{itemtypes}}));
-
- my @results;
- while( my $row = $sth->fetchrow_hashref){
- push @results, {date => $row->{dateaccessioned}
- , biblionumber => $row->{biblionumber}
- , title => $row->{title}};
- }
-
- return @results;
-}
-
-=head2 GetItemnumbersForBiblio
-
- my $itemnumbers = GetItemnumbersForBiblio($biblionumber);
-
-Given a single biblionumber, return an arrayref of all the corresponding itemnumbers
+ my ($record) = @_;
+ my @returnitemsInfo;
-=cut
-
-sub GetItemnumbersForBiblio {
- my $biblionumber = shift;
- my @items;
- my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber = ?");
- $sth->execute($biblionumber);
- while (my $result = $sth->fetchrow_hashref) {
- push @items, $result->{'itemnumber'};
+ if( !C4::Context->preference('EasyAnalyticalRecords') ) {
+ return @returnitemsInfo;
}
- return \@items;
-}
-=head2 get_itemnumbers_of
-
- 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.
-
-=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;
+ my @fields;
+ if( C4::Context->preference('marcflavour') eq 'MARC21' ||
+ C4::Context->preference('marcflavour') eq 'NORMARC') {
+ @fields = $record->field('773');
+ } elsif( C4::Context->preference('marcflavour') eq 'UNIMARC') {
+ @fields = $record->field('461');
}
- return \%itemnumbers_of;
+ foreach my $hostfield ( @fields ) {
+ my $hostbiblionumber = $hostfield->subfield("0");
+ my $linkeditemnumber = $hostfield->subfield("9");
+ my @hostitemInfos = GetItemsInfo($hostbiblionumber);
+ foreach my $hostitemInfo (@hostitemInfos) {
+ if( $hostitemInfo->{itemnumber} eq $linkeditemnumber ) {
+ push @returnitemsInfo, $hostitemInfo;
+ last;
+ }
+ }
+ }
+ return @returnitemsInfo;
}
=head2 get_hostitemnumbers_of
sub get_hostitemnumbers_of {
my ($biblionumber) = @_;
- my $marcrecord = GetMarcBiblio($biblionumber);
+ my $marcrecord = C4::Biblio::GetMarcBiblio({ biblionumber => $biblionumber });
return unless $marcrecord;
foreach my $hostfield ( $marcrecord->field($tag) ) {
my $hostbiblionumber = $hostfield->subfield($biblio_s);
+ next unless $hostbiblionumber; # have tag, don't have $biblio_s subfield
my $linkeditemnumber = $hostfield->subfield($item_s);
- my @itemnumbers;
- if ( my $itemnumbers =
- get_itemnumbers_of($hostbiblionumber)->{$hostbiblionumber} )
- {
- @itemnumbers = @$itemnumbers;
- }
- foreach my $itemnumber (@itemnumbers) {
- if ( $itemnumber eq $linkeditemnumber ) {
- push( @returnhostitemnumbers, $itemnumber );
- last;
- }
+ if ( ! $linkeditemnumber ) {
+ warn "ERROR biblionumber $biblionumber has 773^0, but doesn't have 9";
+ next;
}
+ my $is_from_biblio = Koha::Items->search({ itemnumber => $linkeditemnumber, biblionumber => $hostbiblionumber });
+ push @returnhostitemnumbers, $linkeditemnumber
+ if $is_from_biblio;
}
return @returnhostitemnumbers;
}
-
-=head2 GetItemnumberFromBarcode
-
- $result = GetItemnumberFromBarcode($barcode);
-
-=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 GetBarcodeFromItemnumber
-
- $result = GetBarcodeFromItemnumber($itemnumber);
-
-=cut
-
-sub GetBarcodeFromItemnumber {
- my ($itemnumber) = @_;
- my $dbh = C4::Context->dbh;
-
- my $rq =
- $dbh->prepare("SELECT barcode FROM items WHERE items.itemnumber=?");
- $rq->execute($itemnumber);
- my ($result) = $rq->fetchrow;
- return ($result);
-}
-
=head2 GetHiddenItemnumbers
- my @itemnumbers_to_hide = GetHiddenItemnumbers(@items);
+ my @itemnumbers_to_hide = GetHiddenItemnumbers({ items => \@items, borcat => $category });
Given a list of items it checks which should be hidden from the OPAC given
the current configuration. Returns a list of itemnumbers corresponding to
-those that should be hidden.
+those that should be hidden. Optionally takes a borcat parameter for certain borrower types
+to be excluded
=cut
sub GetHiddenItemnumbers {
- my (@items) = @_;
+ my $params = shift;
+ my $items = $params->{items};
+ if (my $exceptions = C4::Context->preference('OpacHiddenItemsExceptions') and $params->{'borcat'}){
+ foreach my $except (split(/\|/, $exceptions)){
+ if ($params->{'borcat'} eq $except){
+ return; # we don't hide anything for this borrower category
+ }
+ }
+ }
my @resultitems;
my $yaml = C4::Context->preference('OpacHiddenItems');
my $dbh = C4::Context->dbh;
# For each item
- foreach my $item (@items) {
+ foreach my $item (@$items) {
# We check each rule
foreach my $field (keys %$hidingrules) {
my $itemrecord = GetItem($itemnumber);
- # Tack on 'items.' prefix to column names so that TransformKohaToMarc will work.
+ # Tack on 'items.' prefix to column names so that C4::Biblio::TransformKohaToMarc will work.
# Also, don't emit a subfield if the underlying field is blank.
defined($itemrecord->{$_}) && $itemrecord->{$_} ne '' ? ("items.$_" => $itemrecord->{$_}) : ()
} keys %{ $itemrecord }
};
- my $itemmarc = TransformKohaToMarc($mungeditem);
- my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",GetFrameworkCode($biblionumber)||'');
+ my $framework = C4::Biblio::GetFrameworkCode( $biblionumber );
+ my $itemmarc = C4::Biblio::TransformKohaToMarc( $mungeditem ); # Bug 21774: no_split parameter removed to allow cloned subfields
+ my ( $itemtag, $itemsubfield ) = C4::Biblio::GetMarcFromKohaField(
+ "items.itemnumber", $framework,
+ );
my $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($mungeditem->{'items.more_subfields_xml'});
if (defined $unlinked_item_subfields and $#$unlinked_item_subfields > -1) {
my $dbh=C4::Context->dbh;
my $error;
$item->{permanent_location} //= $item->{location};
+ _mod_item_dates( $item );
my $query =
"INSERT INTO items SET
biblionumber = ?,
my $query = "UPDATE items SET ";
my @bind;
+ _mod_item_dates( $item );
for my $key ( keys %$item ) {
next if ( $key eq 'itemnumber' );
$query.="$key=?,";
return ($item->{'itemnumber'},$error);
}
+sub _mod_item_dates { # date formatting for date fields in item hash
+ my ( $item ) = @_;
+ return if !$item || ref($item) ne 'HASH';
+
+ my @keys = grep
+ { $_ =~ /^onloan$|^date|date$|datetime$/ }
+ keys %$item;
+ # Incl. dateaccessioned,replacementpricedate,datelastborrowed,datelastseen
+ # NOTE: We do not (yet) have items fields ending with datetime
+ # Fields with _on$ have been handled already
+
+ foreach my $key ( @keys ) {
+ next if !defined $item->{$key}; # skip undefs
+ my $dt = eval { dt_from_string( $item->{$key} ) };
+ # eval: dt_from_string will die on us if we pass illegal dates
+
+ my $newstr;
+ if( defined $dt && ref($dt) eq 'DateTime' ) {
+ if( $key =~ /datetime/ ) {
+ $newstr = DateTime::Format::MySQL->format_datetime($dt);
+ } else {
+ $newstr = DateTime::Format::MySQL->format_date($dt);
+ }
+ }
+ $item->{$key} = $newstr; # might be undef to clear garbage
+ }
+}
+
=head2 _koha_delete_item
_koha_delete_item( $itemnum );
my $item_marc = MARC::Record->new();
foreach my $item_field ( keys %{$mungeditem} ) {
- my ( $tag, $subfield ) = GetMarcFromKohaField( $item_field, $frameworkcode );
+ my ( $tag, $subfield ) = C4::Biblio::GetMarcFromKohaField( $item_field, $frameworkcode );
next unless defined $tag and defined $subfield; # skip if not mapped to MARC field
my @values = split(/\s?\|\s?/, $mungeditem->{$item_field}, -1);
foreach my $value (@values){
my $original_item_marc = shift;
my $frameworkcode = shift;
- my $marcstructure = GetMarcStructure(1, $frameworkcode, { unsafe => 1 });
+ my $marcstructure = C4::Biblio::GetMarcStructure(1, $frameworkcode, { unsafe => 1 });
# assume that this record has only one field, and that that
# field contains only the item information
return ($result);
}
-=head2 GetItemHolds
-
- $holds = &GetItemHolds($biblionumber, $itemnumber);
-
-This function return the count of holds with $biblionumber and $itemnumber
-
-=cut
-
-sub GetItemHolds {
- my ($biblionumber, $itemnumber) = @_;
- my $holds;
- my $dbh = C4::Context->dbh;
- my $query = "SELECT count(*)
- FROM reserves
- WHERE biblionumber=? AND itemnumber=?";
- my $sth = $dbh->prepare($query);
- $sth->execute($biblionumber, $itemnumber);
- $holds = $sth->fetchrow;
- return $holds;
-}
-
=head2 SearchItemsByField
my $items = SearchItemsByField($field, $value);
$column = $kohafield;
} else {
# MARC field is not linked to a DB field so we need to use
- # ExtractValue on biblioitems.marcxml or
+ # ExtractValue on marcxml from biblio_metadata or
# items.more_subfields_xml, depending on the MARC field.
my $xpath;
my $sqlfield;
- my ($itemfield) = GetMarcFromKohaField('items.itemnumber');
+ my ($itemfield) = C4::Biblio::GetMarcFromKohaField('items.itemnumber');
if ($marcfield eq $itemfield) {
$sqlfield = 'more_subfields_xml';
$xpath = '//record/datafield/subfield[@code="' . $marcsubfield . '"]';
} else {
- $sqlfield = 'marcxml';
+ $sqlfield = 'metadata'; # From biblio_metadata
if ($marcfield < 10) {
$xpath = "//record/controlfield[\@tag=\"$marcfield\"]";
} else {
FROM items
LEFT JOIN biblio ON biblio.biblionumber = items.biblionumber
LEFT JOIN biblioitems ON biblioitems.biblioitemnumber = items.biblioitemnumber
+ LEFT JOIN biblio_metadata ON biblio_metadata.biblionumber = biblio.biblionumber
+ WHERE 1
};
if (defined $where_str and $where_str ne '') {
- $query .= qq{ WHERE $where_str };
+ $query .= qq{ AND $where_str };
}
+ $query .= q{ AND biblio_metadata.format = 'marcxml' AND biblio_metadata.schema = ? };
+ push @where_args, C4::Context->preference('marcflavour');
+
my @columns = Koha::Database->new()->schema()->resultset('Item')->result_source->columns;
push @columns, Koha::Database->new()->schema()->resultset('Biblio')->result_source->columns;
push @columns, Koha::Database->new()->schema()->resultset('Biblioitem')->result_source->columns;
my ( $bibnum, $itemnum, $defaultvalues, $frameworkcode ) = @_;
my $dbh = C4::Context->dbh;
- $frameworkcode = &GetFrameworkCode($bibnum) if $bibnum;
- my ( $itemtagfield, $itemtagsubfield ) = &GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+ $frameworkcode = C4::Biblio::GetFrameworkCode($bibnum) if $bibnum;
+ my ( $itemtagfield, $itemtagsubfield ) = C4::Biblio::GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
# Note: $tagslib obtained from GetMarcStructure() in 'unsafe' mode is
# a shared data structure. No plugin (including custom ones) should change
# its contents. See also GetMarcStructure.
- my $tagslib = &GetMarcStructure( 1, $frameworkcode, { unsafe => 1 } );
+ my $tagslib = GetMarcStructure( 1, $frameworkcode, { unsafe => 1 } );
# return nothing if we don't have found an existing framework.
return q{} unless $tagslib;
if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
&& $defaultvalues
&& $defaultvalues->{'callnumber'} ) {
- if( $itemrecord and $defaultvalues and not $itemrecord->field($subfield) ){
+ if( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ){
# if the item record exists, only use default value if the item has no callnumber
$defaultvalue = $defaultvalues->{callnumber};
} elsif ( !$itemrecord and $defaultvalues ) {
if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' )
&& $defaultvalues
&& $defaultvalues->{'branchcode'} ) {
- if ( $itemrecord and $defaultvalues and not $itemrecord->field($subfield) ) {
+ if ( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ) {
$defaultvalue = $defaultvalues->{branchcode};
}
}
&& $defaultvalues
&& $defaultvalues->{'location'} ) {
- if ( $itemrecord and $defaultvalues and not $itemrecord->field($subfield) ) {
+ if ( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ) {
# if the item record exists, only use default value if the item has no locationr
$defaultvalue = $defaultvalues->{location};
} elsif ( !$itemrecord and $defaultvalues ) {
#----- itemtypes
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
- my $itemtypes = GetItemTypes( style => 'array' );
+ my $itemtypes = Koha::ItemTypes->search_with_localization;
push @authorised_values, ""
unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
- for my $itemtype ( @$itemtypes ) {
- push @authorised_values, $itemtype->{itemtype};
- $authorised_lib{$itemtype->{itemtype}} = $itemtype->{translated_description};
+ while ( my $itemtype = $itemtypes->next ) {
+ push @authorised_values, $itemtype->itemtype;
+ $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description;
+ }
+ if ($defaultvalues && $defaultvalues->{'itemtype'}) {
+ $defaultvalue = $defaultvalues->{'itemtype'};
}
+
#---- class_sources
} elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
push @authorised_values, "" unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
});
my $pars = { dbh => $dbh, record => undef, tagslib =>$tagslib, id => $subfield_data{id}, tabloop => undef };
$plugin->build( $pars );
+ if ( $itemrecord and my $field = $itemrecord->field($tag) ) {
+ $defaultvalue = $field->subfield($subfield);
+ }
if( !$plugin->errstr ) {
#TODO Move html to template; see report 12176/13397
my $tab= $plugin->noclick? '-1': '';
my $class= $plugin->noclick? ' disabled': '';
my $title= $plugin->noclick? 'No popup': 'Tag editor';
- $subfield_data{marc_value} = qq[<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="255" /><a href="#" id="buttonDot_$subfield_data{id}" tabindex="$tab" class="buttonDot $class" title="$title">...</a>\n].$plugin->javascript;
+ $subfield_data{marc_value} = qq[<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="255" value="$defaultvalue" /><a href="#" id="buttonDot_$subfield_data{id}" tabindex="$tab" class="buttonDot $class" title="$title">...</a>\n].$plugin->javascript;
} else {
warn $plugin->errstr;
- $subfield_data{marc_value} = qq(<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="255" />); # supply default input form
+ $subfield_data{marc_value} = qq(<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="255" value="$defaultvalue" />); # supply default input form
}
}
elsif ( $tag eq '' ) { # it's an hidden field