|
Lines 34-41
use C4::Biblio qw(
Link Here
|
| 34 |
); |
34 |
); |
| 35 |
use C4::Context; |
35 |
use C4::Context; |
| 36 |
use C4::Circulation qw( barcodedecode LostItem ); |
36 |
use C4::Circulation qw( barcodedecode LostItem ); |
| 37 |
use C4::Koha qw( GetAuthorisedValues ); |
|
|
| 38 |
use C4::ClassSource qw( GetClassSources GetClassSource ); |
| 39 |
use C4::Barcodes; |
37 |
use C4::Barcodes; |
| 40 |
use C4::Barcodes::ValueBuilder; |
38 |
use C4::Barcodes::ValueBuilder; |
| 41 |
use Koha::DateUtils qw( dt_from_string ); |
39 |
use Koha::DateUtils qw( dt_from_string ); |
|
Lines 48-53
use C4::Search qw( enabled_staff_search_views );
Link Here
|
| 48 |
use Storable qw( freeze thaw ); |
46 |
use Storable qw( freeze thaw ); |
| 49 |
use URI::Escape qw( uri_escape_utf8 ); |
47 |
use URI::Escape qw( uri_escape_utf8 ); |
| 50 |
use C4::Members; |
48 |
use C4::Members; |
|
|
49 |
use Koha::UI::Form::Builder::Item; |
| 51 |
|
50 |
|
| 52 |
use MARC::File::XML; |
51 |
use MARC::File::XML; |
| 53 |
use URI::Escape qw( uri_escape_utf8 ); |
52 |
use URI::Escape qw( uri_escape_utf8 ); |
|
Lines 58-333
use List::MoreUtils qw( any uniq );
Link Here
|
| 58 |
|
57 |
|
| 59 |
our $dbh = C4::Context->dbh; |
58 |
our $dbh = C4::Context->dbh; |
| 60 |
|
59 |
|
| 61 |
sub generate_subfield_form { |
|
|
| 62 |
my ($tag, $subfieldtag, $value, $tagslib,$subfieldlib, $branches, $biblionumber, $temp, $i, $restrictededition, $item) = @_; |
| 63 |
|
| 64 |
my $frameworkcode = &GetFrameworkCode($biblionumber); |
| 65 |
|
| 66 |
$item //= {}; |
| 67 |
|
| 68 |
my %subfield_data; |
| 69 |
my $dbh = C4::Context->dbh; |
| 70 |
|
| 71 |
my $index_subfield = int(rand(1000000)); |
| 72 |
if ($subfieldtag eq '@'){ |
| 73 |
$subfield_data{id} = "tag_".$tag."_subfield_00_".$index_subfield; |
| 74 |
} else { |
| 75 |
$subfield_data{id} = "tag_".$tag."_subfield_".$subfieldtag."_".$index_subfield; |
| 76 |
} |
| 77 |
|
| 78 |
$subfield_data{tag} = $tag; |
| 79 |
$subfield_data{subfield} = $subfieldtag; |
| 80 |
$subfield_data{marc_lib} ="<span id=\"error$i\" title=\"".$subfieldlib->{lib}."\">".$subfieldlib->{lib}."</span>"; |
| 81 |
$subfield_data{mandatory} = $subfieldlib->{mandatory}; |
| 82 |
$subfield_data{important} = $subfieldlib->{important}; |
| 83 |
$subfield_data{repeatable} = $subfieldlib->{repeatable}; |
| 84 |
$subfield_data{maxlength} = $subfieldlib->{maxlength}; |
| 85 |
$subfield_data{display_order} = $subfieldlib->{display_order}; |
| 86 |
$subfield_data{kohafield} = $subfieldlib->{kohafield} || 'items.more_subfields_xml'; |
| 87 |
|
| 88 |
if ( ! defined( $value ) || $value eq '') { |
| 89 |
$value = $subfieldlib->{defaultvalue}; |
| 90 |
if ( $value ) { |
| 91 |
# get today date & replace <<YYYY>>, <<YY>>, <<MM>>, <<DD>> if provided in the default value |
| 92 |
my $today_dt = dt_from_string; |
| 93 |
my $year = $today_dt->strftime('%Y'); |
| 94 |
my $shortyear = $today_dt->strftime('%y'); |
| 95 |
my $month = $today_dt->strftime('%m'); |
| 96 |
my $day = $today_dt->strftime('%d'); |
| 97 |
$value =~ s/<<YYYY>>/$year/g; |
| 98 |
$value =~ s/<<YY>>/$shortyear/g; |
| 99 |
$value =~ s/<<MM>>/$month/g; |
| 100 |
$value =~ s/<<DD>>/$day/g; |
| 101 |
# And <<USER>> with surname (?) |
| 102 |
my $username=(C4::Context->userenv?C4::Context->userenv->{'surname'}:"superlibrarian"); |
| 103 |
$value=~s/<<USER>>/$username/g; |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
$subfield_data{visibility} = "display:none;" if (($subfieldlib->{hidden} > 4) || ($subfieldlib->{hidden} <= -4)); |
| 108 |
|
| 109 |
my $pref_itemcallnumber = C4::Context->preference('itemcallnumber'); |
| 110 |
if (!$value && $subfieldlib->{kohafield} eq 'items.itemcallnumber' && $pref_itemcallnumber) { |
| 111 |
foreach my $pref_itemcallnumber_part (split(/,/, $pref_itemcallnumber)){ |
| 112 |
my $CNtag = substr( $pref_itemcallnumber_part, 0, 3 ); # 3-digit tag number |
| 113 |
my $CNsubfields = substr( $pref_itemcallnumber_part, 3 ); # Any and all subfields |
| 114 |
$CNsubfields = undef if $CNsubfields eq ''; |
| 115 |
my $temp2 = $temp->field($CNtag); |
| 116 |
|
| 117 |
next unless $temp2; |
| 118 |
$value = $temp2->as_string( $CNsubfields, ' ' ); |
| 119 |
last if $value; |
| 120 |
} |
| 121 |
} |
| 122 |
|
| 123 |
my $default_location = C4::Context->preference('NewItemsDefaultLocation'); |
| 124 |
if ( !$value && $subfieldlib->{kohafield} eq 'items.location' && $default_location ) { |
| 125 |
$value = $default_location; |
| 126 |
} |
| 127 |
|
| 128 |
if ($frameworkcode eq 'FA' && $subfieldlib->{kohafield} eq 'items.barcode' && !$value){ |
| 129 |
my $input = CGI->new; |
| 130 |
$value = $input->param('barcode'); |
| 131 |
} |
| 132 |
|
| 133 |
if ( $subfieldlib->{authorised_value} ) { |
| 134 |
my @authorised_values; |
| 135 |
my %authorised_lib; |
| 136 |
# builds list, depending on authorised value... |
| 137 |
if ( $subfieldlib->{authorised_value} eq "LOST" ) { |
| 138 |
my $ClaimReturnedLostValue = C4::Context->preference('ClaimReturnedLostValue'); |
| 139 |
my $item_is_return_claim = $ClaimReturnedLostValue && exists $item->{itemlost} && $ClaimReturnedLostValue eq $item->{itemlost}; |
| 140 |
$subfield_data{IS_RETURN_CLAIM} = $item_is_return_claim; |
| 141 |
|
| 142 |
$subfield_data{IS_LOST_AV} = 1; |
| 143 |
|
| 144 |
push @authorised_values, qq{}; |
| 145 |
my $av = GetAuthorisedValues( $subfieldlib->{authorised_value} ); |
| 146 |
for my $r ( @$av ) { |
| 147 |
push @authorised_values, $r->{authorised_value}; |
| 148 |
$authorised_lib{$r->{authorised_value}} = $r->{lib}; |
| 149 |
} |
| 150 |
} |
| 151 |
elsif ( $subfieldlib->{authorised_value} eq "branches" ) { |
| 152 |
foreach my $thisbranch (@$branches) { |
| 153 |
push @authorised_values, $thisbranch->{branchcode}; |
| 154 |
$authorised_lib{$thisbranch->{branchcode}} = $thisbranch->{branchname}; |
| 155 |
$value = $thisbranch->{branchcode} if $thisbranch->{selected} && !$value; |
| 156 |
} |
| 157 |
} |
| 158 |
elsif ( $subfieldlib->{authorised_value} eq "itemtypes" ) { |
| 159 |
push @authorised_values, ""; |
| 160 |
my $branch_limit = C4::Context->userenv && C4::Context->userenv->{"branch"}; |
| 161 |
my $itemtypes; |
| 162 |
if($branch_limit) { |
| 163 |
$itemtypes = Koha::ItemTypes->search_with_localization({branchcode => $branch_limit}); |
| 164 |
} else { |
| 165 |
$itemtypes = Koha::ItemTypes->search_with_localization; |
| 166 |
} |
| 167 |
while ( my $itemtype = $itemtypes->next ) { |
| 168 |
push @authorised_values, $itemtype->itemtype; |
| 169 |
$authorised_lib{$itemtype->itemtype} = $itemtype->translated_description; |
| 170 |
} |
| 171 |
|
| 172 |
unless ( $value ) { |
| 173 |
my $itype_sth = $dbh->prepare("SELECT itemtype FROM biblioitems WHERE biblionumber = ?"); |
| 174 |
$itype_sth->execute( $biblionumber ); |
| 175 |
( $value ) = $itype_sth->fetchrow_array; |
| 176 |
} |
| 177 |
|
| 178 |
#---- class_sources |
| 179 |
} |
| 180 |
elsif ( $subfieldlib->{authorised_value} eq "cn_source" ) { |
| 181 |
push @authorised_values, ""; |
| 182 |
|
| 183 |
my $class_sources = GetClassSources(); |
| 184 |
my $default_source = C4::Context->preference("DefaultClassificationSource"); |
| 185 |
|
| 186 |
foreach my $class_source (sort keys %$class_sources) { |
| 187 |
next unless $class_sources->{$class_source}->{'used'} or |
| 188 |
($value and $class_source eq $value) or |
| 189 |
($class_source eq $default_source); |
| 190 |
push @authorised_values, $class_source; |
| 191 |
$authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'}; |
| 192 |
} |
| 193 |
$value = $default_source unless ($value); |
| 194 |
|
| 195 |
#---- "true" authorised value |
| 196 |
} |
| 197 |
else { |
| 198 |
push @authorised_values, qq{}; |
| 199 |
my $av = GetAuthorisedValues( $subfieldlib->{authorised_value} ); |
| 200 |
for my $r ( @$av ) { |
| 201 |
push @authorised_values, $r->{authorised_value}; |
| 202 |
$authorised_lib{$r->{authorised_value}} = $r->{lib}; |
| 203 |
} |
| 204 |
} |
| 205 |
|
| 206 |
if ( $subfieldlib->{hidden} > 4 or $subfieldlib->{hidden} <= -4 ) { |
| 207 |
$subfield_data{marc_value} = { |
| 208 |
type => 'hidden', |
| 209 |
id => $subfield_data{id}, |
| 210 |
maxlength => $subfield_data{maxlength}, |
| 211 |
value => $value, |
| 212 |
( ( grep { $_ eq $subfieldlib->{authorised_value}} ( qw(branches itemtypes cn_source) ) ) ? () : ( category => $subfieldlib->{authorised_value}) ), |
| 213 |
}; |
| 214 |
} |
| 215 |
else { |
| 216 |
$subfield_data{marc_value} = { |
| 217 |
type => 'select', |
| 218 |
id => "tag_".$tag."_subfield_".$subfieldtag."_".$index_subfield, |
| 219 |
values => \@authorised_values, |
| 220 |
labels => \%authorised_lib, |
| 221 |
default => $value, |
| 222 |
( ( grep { $_ eq $subfieldlib->{authorised_value}} ( qw(branches itemtypes cn_source) ) ) ? () : ( category => $subfieldlib->{authorised_value}) ), |
| 223 |
}; |
| 224 |
} |
| 225 |
} |
| 226 |
# it's a thesaurus / authority field |
| 227 |
elsif ( $subfieldlib->{authtypecode} ) { |
| 228 |
$subfield_data{marc_value} = { |
| 229 |
type => 'text_auth', |
| 230 |
id => $subfield_data{id}, |
| 231 |
maxlength => $subfield_data{maxlength}, |
| 232 |
value => $value, |
| 233 |
authtypecode => $subfieldlib->{authtypecode}, |
| 234 |
}; |
| 235 |
} |
| 236 |
# it's a plugin field |
| 237 |
elsif ( $subfieldlib->{value_builder} ) { # plugin |
| 238 |
require Koha::FrameworkPlugin; |
| 239 |
my $plugin = Koha::FrameworkPlugin->new({ |
| 240 |
name => $subfieldlib->{'value_builder'}, |
| 241 |
item_style => 1, |
| 242 |
}); |
| 243 |
my $pars= { dbh => $dbh, record => $temp, tagslib =>$tagslib, |
| 244 |
id => $subfield_data{id} }; |
| 245 |
$plugin->build( $pars ); |
| 246 |
if( !$plugin->errstr ) { |
| 247 |
my $class= 'buttonDot'. ( $plugin->noclick? ' disabled': '' ); |
| 248 |
$subfield_data{marc_value} = { |
| 249 |
type => 'text_plugin', |
| 250 |
id => $subfield_data{id}, |
| 251 |
maxlength => $subfield_data{maxlength}, |
| 252 |
value => $value, |
| 253 |
class => $class, |
| 254 |
nopopup => $plugin->noclick, |
| 255 |
javascript => $plugin->javascript, |
| 256 |
}; |
| 257 |
} else { |
| 258 |
warn $plugin->errstr; |
| 259 |
$subfield_data{marc_value} = { |
| 260 |
type => 'text', |
| 261 |
id => $subfield_data{id}, |
| 262 |
maxlength => $subfield_data{maxlength}, |
| 263 |
value => $value, |
| 264 |
}; # supply default input form |
| 265 |
} |
| 266 |
} |
| 267 |
elsif ( $tag eq '' ) { # it's an hidden field |
| 268 |
$subfield_data{marc_value} = { |
| 269 |
type => 'hidden', |
| 270 |
id => $subfield_data{id}, |
| 271 |
maxlength => $subfield_data{maxlength}, |
| 272 |
value => $value, |
| 273 |
}; |
| 274 |
} |
| 275 |
elsif ( $subfieldlib->{'hidden'} ) { # FIXME: shouldn't input type be "hidden" ? |
| 276 |
$subfield_data{marc_value} = { |
| 277 |
type => 'text', |
| 278 |
id => $subfield_data{id}, |
| 279 |
maxlength => $subfield_data{maxlength}, |
| 280 |
value => $value, |
| 281 |
}; |
| 282 |
} |
| 283 |
elsif ( |
| 284 |
( |
| 285 |
$value and length($value) > 100 |
| 286 |
) |
| 287 |
or ( |
| 288 |
C4::Context->preference("marcflavour") eq "UNIMARC" |
| 289 |
and 300 <= $tag && $tag < 400 && $subfieldtag eq 'a' |
| 290 |
) |
| 291 |
or ( |
| 292 |
C4::Context->preference("marcflavour") eq "MARC21" |
| 293 |
and 500 <= $tag && $tag < 600 |
| 294 |
) |
| 295 |
) { |
| 296 |
# oversize field (textarea) |
| 297 |
$subfield_data{marc_value} = { |
| 298 |
type => 'textarea', |
| 299 |
id => $subfield_data{id}, |
| 300 |
value => $value, |
| 301 |
}; |
| 302 |
} else { |
| 303 |
# it's a standard field |
| 304 |
$subfield_data{marc_value} = { |
| 305 |
type => 'text', |
| 306 |
id => $subfield_data{id}, |
| 307 |
maxlength => $subfield_data{maxlength}, |
| 308 |
value => $value, |
| 309 |
}; |
| 310 |
} |
| 311 |
|
| 312 |
# Getting list of subfields to keep when restricted editing is enabled |
| 313 |
my $subfieldsToAllowForRestrictedEditing = C4::Context->preference('SubfieldsToAllowForRestrictedEditing'); |
| 314 |
my $allowAllSubfields = ( |
| 315 |
not defined $subfieldsToAllowForRestrictedEditing |
| 316 |
or $subfieldsToAllowForRestrictedEditing eq q|| |
| 317 |
) ? 1 : 0; |
| 318 |
my @subfieldsToAllow = split(/ /, $subfieldsToAllowForRestrictedEditing); |
| 319 |
|
| 320 |
# If we're on restricted editing, and our field is not in the list of subfields to allow, |
| 321 |
# then it is read-only |
| 322 |
$subfield_data{marc_value}->{readonly} = ( |
| 323 |
not $allowAllSubfields |
| 324 |
and $restrictededition |
| 325 |
and !grep { $tag . '$' . $subfieldtag eq $_ } @subfieldsToAllow |
| 326 |
) ? 1: 0; |
| 327 |
|
| 328 |
return \%subfield_data; |
| 329 |
} |
| 330 |
|
| 331 |
sub get_item_from_cookie { |
60 |
sub get_item_from_cookie { |
| 332 |
my ( $input ) = @_; |
61 |
my ( $input ) = @_; |
| 333 |
|
62 |
|
|
Lines 808-821
my @header_value_loop = map {
Link Here
|
| 808 |
} |
537 |
} |
| 809 |
} sort keys %$subfieldcode_attribute_mappings; |
538 |
} sort keys %$subfieldcode_attribute_mappings; |
| 810 |
|
539 |
|
| 811 |
# now, build the item form for entering a new item |
|
|
| 812 |
my $branch = $input->param('branch') || C4::Context->userenv->{branch}; |
| 813 |
my $libraries = Koha::Libraries->search({}, { order_by => ['branchname'] })->unblessed;# build once ahead of time, instead of multiple times later. |
| 814 |
for my $library ( @$libraries ) { |
| 815 |
$library->{selected} = 1 if $library->{branchcode} eq $branch |
| 816 |
} |
| 817 |
|
| 818 |
|
| 819 |
# Using last created item if it exists |
540 |
# Using last created item if it exists |
| 820 |
if ( $prefillitem |
541 |
if ( $prefillitem |
| 821 |
&& $op ne "additem" |
542 |
&& $op ne "additem" |
|
Lines 825-908
if ( $prefillitem
Link Here
|
| 825 |
$current_item = $item_from_cookie if $item_from_cookie; |
546 |
$current_item = $item_from_cookie if $item_from_cookie; |
| 826 |
} |
547 |
} |
| 827 |
|
548 |
|
| 828 |
my @subfields_to_prefill = split ' ', C4::Context->preference('SubfieldsToUseWhenPrefill'); |
|
|
| 829 |
|
| 830 |
if ( $current_item->{more_subfields_xml} ) { |
549 |
if ( $current_item->{more_subfields_xml} ) { |
|
|
550 |
# FIXME Use Maybe MARC::Record::new_from_xml if encoding issues on subfield (??) |
| 831 |
$current_item->{marc_more_subfields_xml} = MARC::Record->new_from_xml($current_item->{more_subfields_xml}, 'UTF-8'); |
551 |
$current_item->{marc_more_subfields_xml} = MARC::Record->new_from_xml($current_item->{more_subfields_xml}, 'UTF-8'); |
| 832 |
} |
552 |
} |
| 833 |
|
553 |
|
| 834 |
# We generate form, and fill with values if defined |
554 |
my $branchcode = $input->param('branch') || C4::Context->userenv->{branch}; |
| 835 |
my $temp = GetMarcBiblio({ biblionumber => $biblionumber }); |
|
|
| 836 |
my $i = 0; |
| 837 |
my @subfields; |
| 838 |
foreach my $tag ( keys %{$tagslib} ) { |
| 839 |
foreach my $subtag ( keys %{ $tagslib->{$tag} } ) { |
| 840 |
|
| 841 |
my $subfield = $tagslib->{$tag}{$subtag}; |
| 842 |
|
| 843 |
next if IsMarcStructureInternal( $subfield ); |
| 844 |
next if ( $subfield->{tab} ne "10" ); |
| 845 |
|
| 846 |
my @values = (); |
| 847 |
|
| 848 |
my $subfield_data; |
| 849 |
|
| 850 |
# If we are not adding a new item |
| 851 |
# OR |
| 852 |
# If the subfield must be prefilled with last catalogued item |
| 853 |
if ( |
| 854 |
$nextop ne 'additem' |
| 855 |
|| ( |
| 856 |
!$prefillitem |
| 857 |
|| ( $prefillitem && grep { $_ eq $subtag } |
| 858 |
@subfields_to_prefill ) |
| 859 |
) |
| 860 |
) |
| 861 |
{ |
| 862 |
my $kohafield = $subfield->{kohafield}; |
| 863 |
if ($kohafield) { |
| 864 |
|
| 865 |
# This is a mapped field |
| 866 |
( my $attribute = $kohafield ) =~ s|^items\.||; |
| 867 |
push @values, $subfield->{repeatable} |
| 868 |
? split '\s\|\s', $current_item->{$attribute} |
| 869 |
: $current_item->{$attribute} |
| 870 |
if defined $current_item->{$attribute}; |
| 871 |
} else { |
| 872 |
# Not mapped, picked the values from more_subfields_xml's MARC |
| 873 |
my $marc_more = $current_item->{marc_more_subfields_xml}; |
| 874 |
if ( $marc_more ) { |
| 875 |
for my $f ( $marc_more->fields($tag) ) { |
| 876 |
push @values, $f->subfield($subtag); |
| 877 |
} |
| 878 |
} |
| 879 |
} |
| 880 |
} |
| 881 |
|
555 |
|
| 882 |
@values = ('') unless @values; |
556 |
# If we are not adding a new item |
| 883 |
|
557 |
# OR |
| 884 |
for my $value (@values) { |
558 |
# If the subfield must be prefilled with last catalogued item |
| 885 |
my $subfield_data = generate_subfield_form( |
559 |
my @subfields_to_prefill; |
| 886 |
$tag, $subtag, |
560 |
if ( $nextop eq 'additem' && $prefillitem ) { |
| 887 |
$value, $tagslib, |
561 |
# Setting to 1 element if SubfieldsToUseWhenPrefill is empty to prevent all the subfields to be prefilled |
| 888 |
$subfield, $libraries, |
562 |
@subfields_to_prefill = split(' ', C4::Context->preference('SubfieldsToUseWhenPrefill')) || (""); |
| 889 |
$biblionumber, $temp, |
563 |
} |
| 890 |
$i, |
564 |
my $subfields = |
| 891 |
$restrictededition, $current_item, |
565 |
Koha::UI::Form::Builder::Item->new( |
| 892 |
); |
566 |
{ biblionumber => $biblionumber, item => $current_item } )->edit_form( |
| 893 |
push @subfields, $subfield_data; |
567 |
{ |
| 894 |
$i++; |
568 |
branchcode => $branchcode, |
| 895 |
} |
569 |
restricted_editition => $restrictededition, |
|
|
570 |
( |
| 571 |
@subfields_to_prefill |
| 572 |
? ( subfields_to_prefill => \@subfields_to_prefill ) |
| 573 |
: () |
| 574 |
) |
| 896 |
} |
575 |
} |
|
|
576 |
); |
| 577 |
|
| 578 |
if( my $default_location = C4::Context->preference('NewItemsDefaultLocation') ) { |
| 579 |
my ( $location_field ) = grep {$_->{kohafield} eq 'items.location'} @$subfields; |
| 580 |
$location_field->{marc_value}->{value} ||= $default_location; |
| 897 |
} |
581 |
} |
| 898 |
@subfields = sort { $a->{display_order} <=> $b->{display_order} || $a->{subfield} cmp $b->{subfield} } @subfields; |
|
|
| 899 |
|
582 |
|
| 900 |
# what's the next op ? it's what we are not in : an add if we're editing, otherwise, and edit. |
583 |
# what's the next op ? it's what we are not in : an add if we're editing, otherwise, and edit. |
| 901 |
$template->param( |
584 |
$template->param( |
| 902 |
biblio => $biblio, |
585 |
biblio => $biblio, |
| 903 |
items => \@items, |
586 |
items => \@items, |
| 904 |
item_header_loop => \@header_value_loop, |
587 |
item_header_loop => \@header_value_loop, |
| 905 |
subfields => \@subfields, |
588 |
subfields => $subfields, |
| 906 |
itemnumber => $itemnumber, |
589 |
itemnumber => $itemnumber, |
| 907 |
barcode => $current_item->{barcode}, |
590 |
barcode => $current_item->{barcode}, |
| 908 |
itemtagfield => $itemtagfield, |
591 |
itemtagfield => $itemtagfield, |
| 909 |
- |
|
|