use Modern::Perl;
-use vars qw(@ISA @EXPORT);
+our (@ISA, @EXPORT_OK);
BEGIN {
require Exporter;
@ISA = qw(Exporter);
- @EXPORT = qw(
+ @EXPORT_OK = qw(
AddItemFromMarc
AddItemBatchFromMarc
ModItemFromMarc
GetHostItemsInfo
get_hostitemnumbers_of
GetHiddenItemnumbers
- MoveItemFromBiblio
+ GetMarcItem
CartToShelf
GetAnalyticsCount
SearchItems
PrepareItemrecordDisplay
+ ToggleNewStatus
);
}
-use Carp;
-use Try::Tiny;
+use Carp qw( croak );
use C4::Context;
use C4::Koha;
-use C4::Biblio;
-use Koha::DateUtils;
+use C4::Biblio qw( GetMarcStructure TransformMarcToKoha );
+use Koha::DateUtils qw( dt_from_string output_pref );
use MARC::Record;
-use C4::ClassSource;
-use C4::Log;
-use List::MoreUtils qw(any);
-use YAML::XS;
+use C4::ClassSource qw( GetClassSort GetClassSources GetClassSource );
+use C4::Log qw( logaction );
+use List::MoreUtils qw( any );
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::DateUtils qw( dt_from_string output_pref );
use Koha::Database;
use Koha::Biblioitems;
my $item_object = Koha::Items->find($itemnumber);
my $item = TransformMarcToKoha( $localitemmarc, $frameworkcode, 'items' );
+ my ( $perm_loc_tag, $perm_loc_subfield ) = C4::Biblio::GetMarcFromKohaField( "items.permanent_location" );
+ my $has_permanent_location = defined $perm_loc_tag && defined $item_marc->subfield( $perm_loc_tag, $perm_loc_subfield );
+
# Retrieving the values for the fields that are not linked
my @mapped_fields = Koha::MarcSubfieldStructures->search(
{
$item_object = $item_object->set_or_blank($item);
$item_object->cn_sort($existing_cn_sort); # Resetting to the existing value
+ $item_object->make_column_dirty('permanent_location') if $has_permanent_location;
+
my $unlinked_item_subfields = _get_unlinked_item_subfields( $localitemmarc, $frameworkcode );
$item_object->more_subfields_xml(_get_unlinked_subfields_xml($unlinked_item_subfields));
$item_object->store({ skip_record_index => $params->{skip_record_index} });
my $dbh = C4::Context->dbh;
my $item = Koha::Items->find( $itemnumber );
- # Remove the 'shelving cart' location status if it is being used.
- CartToShelf( $itemnumber ) if $item->location && $item->location eq 'CART' && ( !$item->permanent_location || $item->permanent_location ne 'CART' );
-
- $dbh->do("UPDATE branchtransfers SET datearrived = NOW(), comments = ? WHERE itemnumber = ? AND datearrived IS NULL", undef, "Canceled, new transfer from $frombranch to $tobranch created", $itemnumber);
+ # NOTE: This retains the existing hard coded behaviour by ignoring transfer limits
+ # and always replacing any existing transfers. (In theory, calls to ModItemTransfer
+ # will have been preceded by a check of branch transfer limits)
+ my $to_library = Koha::Libraries->find($tobranch);
+ my $transfer = $item->request_transfer(
+ {
+ to => $to_library,
+ reason => $trigger,
+ ignore_limits => 1,
+ replace => 1
+ }
+ );
- #new entry in branchtransfers....
- my $sth = $dbh->prepare(
- "INSERT INTO branchtransfers (itemnumber, frombranch, datesent, tobranch, reason)
- VALUES (?, ?, NOW(), ?, ?)");
- $sth->execute($itemnumber, $frombranch, $tobranch, $trigger);
+ # Immediately set the item to in transit if it is checked in
+ if ( !$item->checkout ) {
+ $item->holdingbranch($frombranch)->store(
+ {
+ log_action => 0,
+ skip_record_index => $params->{skip_record_index}
+ }
+ );
+ $transfer->transit;
+ }
- # FIXME we are fetching the item twice in the 2 next statements!
- Koha::Items->find($itemnumber)->holdingbranch($frombranch)->store({ log_action => 0, skip_record_index => $params->{skip_record_index} });
- ModDateLastSeen($itemnumber, undef, { skip_record_index => $params->{skip_record_index} });
return;
}
'+select' => [ 'marc_subfield_structures.kohafield', 'marc_subfield_structures.frameworkcode', 'me.authorised_value', 'me.lib' ],
'+as' => [ 'kohafield', 'frameworkcode', 'authorised_value', 'lib' ],
}
- );
+ )->as_list;
my $avmapping = { map { $_->get_column('kohafield') . ',' . $_->get_column('frameworkcode') . ',' . $_->get_column('authorised_value') => $_->get_column('lib') } @avs };
}
return $serial
- ? sort { ($b->{'publisheddate'} || $b->{'enumchron'}) cmp ($a->{'publisheddate'} || $a->{'enumchron'}) } @results
+ ? sort { ($b->{'publisheddate'} || $b->{'enumchron'} || "") cmp ($a->{'publisheddate'} || $a->{'enumchron'} || "") } @results
: @results;
}
Item's call number normalized for sorting
=back
-
+
=cut
sub GetItemsLocationInfo {
}
my @fields;
- if( C4::Context->preference('marcflavour') eq 'MARC21' ||
- C4::Context->preference('marcflavour') eq 'NORMARC') {
+ if( C4::Context->preference('marcflavour') eq 'MARC21' ) {
@fields = $record->field('773');
} elsif( C4::Context->preference('marcflavour') eq 'UNIMARC') {
@fields = $record->field('461');
my ( @returnhostitemnumbers, $tag, $biblio_s, $item_s );
my $marcflavor = C4::Context->preference('marcflavour');
- if ( $marcflavor eq 'MARC21' || $marcflavor eq 'NORMARC' ) {
+ if ( $marcflavor eq 'MARC21' ) {
$tag = '773';
$biblio_s = '0';
$item_s = '9';
}
my @resultitems;
- my $yaml = C4::Context->preference('OpacHiddenItems');
- return () if (! $yaml =~ /\S/ );
- $yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt
- my $hidingrules;
- eval {
- $hidingrules = YAML::XS::Load($yaml);
- };
- if ($@) {
- warn "Unable to parse OpacHiddenItems syspref : $@";
- return ();
- }
+ my $hidingrules = C4::Context->yaml_preference('OpacHiddenItems');
+
+ return
+ unless $hidingrules;
+
my $dbh = C4::Context->dbh;
# For each item
=cut
-=head2 MoveItemFromBiblio
-
- MoveItemFromBiblio($itenumber, $frombiblio, $tobiblio);
-
-Moves an item from a biblio to another
-
-Returns undef if the move failed or the biblionumber of the destination record otherwise
-
-=cut
-
-sub MoveItemFromBiblio {
- my ($itemnumber, $frombiblio, $tobiblio) = @_;
- my $dbh = C4::Context->dbh;
- my ( $tobiblioitem ) = $dbh->selectrow_array(q|
- SELECT biblioitemnumber
- FROM biblioitems
- WHERE biblionumber = ?
- |, undef, $tobiblio );
- my $return = $dbh->do(q|
- UPDATE items
- SET biblioitemnumber = ?,
- biblionumber = ?
- WHERE itemnumber = ?
- AND biblionumber = ?
- |, undef, $tobiblioitem, $tobiblio, $itemnumber, $frombiblio );
- if ($return == 1) {
- my $indexer = Koha::SearchEngine::Indexer->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
- $indexer->index_records( $tobiblio, "specialUpdate", "biblioserver" );
- $indexer->index_records( $frombiblio, "specialUpdate", "biblioserver" );
- # Checking if the item we want to move is in an order
- require C4::Acquisition;
- my $order = C4::Acquisition::GetOrderFromItemnumber($itemnumber);
- if ($order) {
- # Replacing the biblionumber within the order if necessary
- $order->{'biblionumber'} = $tobiblio;
- C4::Acquisition::ModOrder($order);
- }
-
- # Update reserves, hold_fill_targets, tmp_holdsqueue and linktracker tables
- for my $table_name ( qw( reserves hold_fill_targets tmp_holdsqueue linktracker ) ) {
- $dbh->do( qq|
- UPDATE $table_name
- SET biblionumber = ?
- WHERE itemnumber = ?
- |, undef, $tobiblio, $itemnumber );
- }
- return $tobiblio;
- }
- return;
-}
-
=head2 _marc_from_item_hash
my $item_marc = _marc_from_item_hash($item, $frameworkcode[, $unlinked_item_subfields]);
=head2 PrepareItemrecordDisplay
- PrepareItemrecordDisplay($itemrecord,$bibnum,$itemumber,$frameworkcode);
+ PrepareItemrecordDisplay($bibnum,$itemumber,$defaultvalues,$frameworkcode);
Returns a hash with all the fields for Display a given item data in a template
+$defaultvalues should either contain a hashref of values for the new item, or be undefined.
+
The $frameworkcode returns the item for the given frameworkcode, ONLY if bibnum is not provided
=cut
# its contents. See also GetMarcStructure.
my $tagslib = GetMarcStructure( 1, $frameworkcode, { unsafe => 1 } );
+ # Pick the default location from NewItemsDefaultLocation
+ if ( C4::Context->preference('NewItemsDefaultLocation') ) {
+ $defaultvalues //= {};
+ $defaultvalues->{location} //= C4::Context->preference('NewItemsDefaultLocation');
+ }
+
# return nothing if we don't have found an existing framework.
return q{} unless $tagslib;
my $itemrecord;
# loop through each subfield
my $cntsubf;
- foreach my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
- next if IsMarcStructureInternal($tagslib->{$tag}{$subfield});
- next unless ( $tagslib->{$tag}->{$subfield}->{'tab'} );
- next if ( $tagslib->{$tag}->{$subfield}->{'tab'} ne "10" );
+ foreach my $subfield (
+ sort { $a->{display_order} <=> $b->{display_order} || $a->{subfield} cmp $b->{subfield} }
+ grep { ref($_) && %$_ } # Not a subfield (values for "important", "lib", "mandatory", etc.) or empty
+ values %{ $tagslib->{$tag} } )
+ {
+ next unless ( $subfield->{'tab'} );
+ next if ( $subfield->{'tab'} ne "10" );
my %subfield_data;
$subfield_data{tag} = $tag;
- $subfield_data{subfield} = $subfield;
+ $subfield_data{subfield} = $subfield->{subfield};
$subfield_data{countsubfield} = $cntsubf++;
- $subfield_data{kohafield} = $tagslib->{$tag}->{$subfield}->{'kohafield'};
- $subfield_data{id} = "tag_".$tag."_subfield_".$subfield."_".int(rand(1000000));
+ $subfield_data{kohafield} = $subfield->{kohafield};
+ $subfield_data{id} = "tag_".$tag."_subfield_".$subfield->{subfield}."_".int(rand(1000000));
# $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib};
- $subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib};
- $subfield_data{mandatory} = $tagslib->{$tag}->{$subfield}->{mandatory};
- $subfield_data{repeatable} = $tagslib->{$tag}->{$subfield}->{repeatable};
+ $subfield_data{marc_lib} = $subfield->{lib};
+ $subfield_data{mandatory} = $subfield->{mandatory};
+ $subfield_data{repeatable} = $subfield->{repeatable};
$subfield_data{hidden} = "display:none"
- if ( ( $tagslib->{$tag}->{$subfield}->{hidden} > 4 )
- || ( $tagslib->{$tag}->{$subfield}->{hidden} < -4 ) );
+ if ( ( $subfield->{hidden} > 4 )
+ || ( $subfield->{hidden} < -4 ) );
my ( $x, $defaultvalue );
if ($itemrecord) {
- ( $x, $defaultvalue ) = _find_value( $tag, $subfield, $itemrecord );
+ ( $x, $defaultvalue ) = _find_value( $tag, $subfield->{subfield}, $itemrecord );
}
- $defaultvalue = $tagslib->{$tag}->{$subfield}->{defaultvalue} unless $defaultvalue;
+ $defaultvalue = $subfield->{defaultvalue} unless $defaultvalue;
if ( !defined $defaultvalue ) {
$defaultvalue = q||;
} else {
$defaultvalue =~ s/<<USER>>/$username/g;
}
- my $maxlength = $tagslib->{$tag}->{$subfield}->{maxlength};
+ my $maxlength = $subfield->{maxlength};
# search for itemcallnumber if applicable
- if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
+ if ( $subfield->{kohafield} eq 'items.itemcallnumber'
&& C4::Context->preference('itemcallnumber') && $itemrecord) {
foreach my $itemcn_pref (split(/,/,C4::Context->preference('itemcallnumber'))){
my $CNtag = substr( $itemcn_pref, 0, 3 );
next unless my $field = $itemrecord->field($CNtag);
my $CNsubfields = substr( $itemcn_pref, 3 );
+ $CNsubfields = undef if $CNsubfields eq '';
$defaultvalue = $field->as_string( $CNsubfields, ' ');
last if $defaultvalue;
}
}
- if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.itemcallnumber'
+ if ( $subfield->{kohafield} eq 'items.itemcallnumber'
&& $defaultvalues
&& $defaultvalues->{'callnumber'} ) {
- if( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ){
+ if( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield->{subfield}) ){
# if the item record exists, only use default value if the item has no callnumber
$defaultvalue = $defaultvalues->{callnumber};
} elsif ( !$itemrecord and $defaultvalues ) {
$defaultvalue = $defaultvalues->{callnumber};
}
}
- if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.holdingbranch' || $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.homebranch' )
+ if ( ( $subfield->{kohafield} eq 'items.holdingbranch' || $subfield->{kohafield} eq 'items.homebranch' )
&& $defaultvalues
&& $defaultvalues->{'branchcode'} ) {
if ( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ) {
$defaultvalue = $defaultvalues->{branchcode};
}
}
- if ( ( $tagslib->{$tag}->{$subfield}->{kohafield} eq 'items.location' )
+ if ( ( $subfield->{kohafield} eq 'items.location' )
&& $defaultvalues
&& $defaultvalues->{'location'} ) {
- if ( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield) ) {
+ if ( $itemrecord and $defaultvalues and not $itemrecord->subfield($tag,$subfield->{subfield}) ) {
# if the item record exists, only use default value if the item has no locationr
$defaultvalue = $defaultvalues->{location};
} elsif ( !$itemrecord and $defaultvalues ) {
$defaultvalue = $defaultvalues->{location};
}
}
- if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
+ if ( $subfield->{authorised_value} ) {
my @authorised_values;
my %authorised_lib;
# builds list, depending on authorised value...
#---- branch
- if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
+ if ( $subfield->{'authorised_value'} eq "branches" ) {
if ( ( C4::Context->preference("IndependentBranches") )
&& !C4::Context->IsSuperLibrarian() ) {
my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches WHERE branchcode = ? ORDER BY branchname" );
$sth->execute( C4::Context->userenv->{branch} );
push @authorised_values, ""
- unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+ unless ( $subfield->{mandatory} );
while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) {
push @authorised_values, $branchcode;
$authorised_lib{$branchcode} = $branchname;
my $sth = $dbh->prepare( "SELECT branchcode,branchname FROM branches ORDER BY branchname" );
$sth->execute;
push @authorised_values, ""
- unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
+ unless ( $subfield->{mandatory} );
while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) {
push @authorised_values, $branchcode;
$authorised_lib{$branchcode} = $branchname;
}
#----- itemtypes
- } elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
+ } elsif ( $subfield->{authorised_value} eq "itemtypes" ) {
my $itemtypes = Koha::ItemTypes->search_with_localization;
push @authorised_values, "";
while ( my $itemtype = $itemtypes->next ) {
}
#---- class_sources
- } elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
+ } elsif ( $subfield->{authorised_value} eq "cn_source" ) {
push @authorised_values, "";
my $class_sources = GetClassSources();
#---- "true" authorised value
} else {
$authorised_values_sth->execute(
- $tagslib->{$tag}->{$subfield}->{authorised_value},
+ $subfield->{authorised_value},
$branch_limit ? $branch_limit : ()
);
push @authorised_values, "";
default => $defaultvalue // q{},
labels => \%authorised_lib,
};
- } elsif ( $tagslib->{$tag}->{$subfield}->{value_builder} ) {
+ } elsif ( $subfield->{value_builder} ) {
# it is a plugin
require Koha::FrameworkPlugin;
my $plugin = Koha::FrameworkPlugin->new({
- name => $tagslib->{$tag}->{$subfield}->{value_builder},
+ name => $subfield->{value_builder},
item_style => 1,
});
- my $pars = { dbh => $dbh, record => undef, tagslib =>$tagslib, id => $subfield_data{id}, tabloop => undef };
+ my $pars = { dbh => $dbh, record => undef, tagslib =>$tagslib, id => $subfield_data{id} };
$plugin->build( $pars );
if ( $itemrecord and my $field = $itemrecord->field($tag) ) {
- $defaultvalue = $field->subfield($subfield) || q{};
+ $defaultvalue = $field->subfield($subfield->{subfield}) || q{};
}
if( !$plugin->errstr ) {
#TODO Move html to template; see report 12176/13397
elsif ( $tag eq '' ) { # it's an hidden field
$subfield_data{marc_value} = qq(<input type="hidden" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="$maxlength" value="$defaultvalue" />);
}
- elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ?
+ elsif ( $subfield->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ?
$subfield_data{marc_value} = qq(<input type="text" id="$subfield_data{id}" name="field_value" class="input_marceditor" size="50" maxlength="$maxlength" value="$defaultvalue" />);
}
elsif ( length($defaultvalue) > 100
or (C4::Context->preference("marcflavour") eq "UNIMARC" and
- 300 <= $tag && $tag < 400 && $subfield eq 'a' )
+ 300 <= $tag && $tag < 400 && $subfield->{subfield} eq 'a' )
or (C4::Context->preference("marcflavour") eq "MARC21" and
500 <= $tag && $tag < 600 )
) {