1 package Koha::UI::Form::Builder::Item;
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 use C4::Biblio qw( GetFrameworkCode GetMarcBiblio GetMarcStructure IsMarcStructureInternal );
21 use C4::Koha qw( GetAuthorisedValues );
22 use C4::ClassSource qw( GetClassSources );
24 use Koha::DateUtils qw( dt_from_string );
29 Koha::UI::Form::Builder::Item
31 Helper to build a form to add or edit a new item.
41 my $form = Koha::UI::Form::Builder::Item->new(
43 biblionumber => $biblionumber,
44 item => $current_item,
49 biblionumber should be passed if we are creating a new item.
50 For edition, an hashref representing the item to edit item must be passed.
56 my ( $class, $params ) = @_;
59 $self->{biblionumber} = $params->{biblionumber};
60 $self->{item} = $params->{item};
66 =head3 generate_subfield_form
68 Generate subfield's info for given tag, subfieldtag, etc.
72 sub generate_subfield_form {
74 my ($self, $params) = @_;
75 my $tag = $params->{tag};
76 my $subfieldtag = $params->{subfieldtag};
77 my $value = $params->{value};
78 my $tagslib = $params->{tagslib};
79 my $libraries = $params->{libraries};
80 my $marc_record = $params->{marc_record};
81 my $restricted_edition = $params->{restricted_editition};
82 my $prefill_with_default_values = $params->{prefill_with_default_values};
83 my $branch_limit = $params->{branch_limit};
84 my $default_branches_empty = $params->{default_branches_empty};
86 my $item = $self->{item};
87 my $subfield = $tagslib->{$tag}{$subfieldtag};
88 my $biblionumber = $self->{biblionumber};
90 my $frameworkcode = $biblionumber ? GetFrameworkCode($biblionumber) : q{};
93 my $dbh = C4::Context->dbh;
95 my $index_subfield = int( rand(1000000) );
96 if ( $subfieldtag eq '@' ) {
97 $subfield_data{id} = "tag_" . $tag . "_subfield_00_" . $index_subfield;
101 "tag_" . $tag . "_subfield_" . $subfieldtag . "_" . $index_subfield;
104 $subfield_data{tag} = $tag;
105 $subfield_data{subfield} = $subfieldtag;
106 $subfield_data{marc_lib} =
108 . $subfield->{lib} . "\">"
111 $subfield_data{mandatory} = $subfield->{mandatory};
112 $subfield_data{important} = $subfield->{important};
113 $subfield_data{repeatable} = $subfield->{repeatable};
114 $subfield_data{maxlength} = $subfield->{maxlength};
115 $subfield_data{display_order} = $subfield->{display_order};
116 $subfield_data{kohafield} =
117 $subfield->{kohafield} || 'items.more_subfields_xml';
119 if ( $prefill_with_default_values && ( !defined($value) || $value eq '' ) ) {
120 $value = $subfield->{defaultvalue};
123 # get today date & replace <<YYYY>>, <<YY>>, <<MM>>, <<DD>> if provided in the default value
124 my $today_dt = dt_from_string;
125 my $year = $today_dt->strftime('%Y');
126 my $shortyear = $today_dt->strftime('%y');
127 my $month = $today_dt->strftime('%m');
128 my $day = $today_dt->strftime('%d');
129 $value =~ s/<<YYYY>>/$year/g;
130 $value =~ s/<<YY>>/$shortyear/g;
131 $value =~ s/<<MM>>/$month/g;
132 $value =~ s/<<DD>>/$day/g;
134 # And <<USER>> with surname (?)
137 ? C4::Context->userenv->{'surname'}
140 $value =~ s/<<USER>>/$username/g;
144 $subfield_data{visibility} = "display:none;"
145 if ( ( $subfield->{hidden} > 4 ) || ( $subfield->{hidden} <= -4 ) );
147 my $pref_itemcallnumber = C4::Context->preference('itemcallnumber');
148 if ( $prefill_with_default_values
150 && $subfield->{kohafield}
151 && $subfield->{kohafield} eq 'items.itemcallnumber'
152 && $pref_itemcallnumber )
155 my $pref_itemcallnumber_part ( split( /,/, $pref_itemcallnumber ) )
158 substr( $pref_itemcallnumber_part, 0, 3 ); # 3-digit tag number
160 substr( $pref_itemcallnumber_part, 3 ); # Any and all subfields
161 $CNsubfields = undef if $CNsubfields eq '';
162 my $temp2 = $marc_record->field($CNtag);
165 $value = $temp2->as_string( $CNsubfields, ' ' );
170 if ( $subfield->{authorised_value} ) {
171 my @authorised_values;
174 # builds list, depending on authorised value...
175 if ( $subfield->{authorised_value} eq "LOST" ) {
176 my $ClaimReturnedLostValue =
177 C4::Context->preference('ClaimReturnedLostValue');
178 my $item_is_return_claim =
179 $ClaimReturnedLostValue
180 && exists $item->{itemlost}
181 && $ClaimReturnedLostValue eq $item->{itemlost};
182 $subfield_data{IS_RETURN_CLAIM} = $item_is_return_claim;
184 $subfield_data{IS_LOST_AV} = 1;
186 push @authorised_values, qq{};
187 my $av = GetAuthorisedValues( $subfield->{authorised_value} );
189 push @authorised_values, $r->{authorised_value};
190 $authorised_lib{ $r->{authorised_value} } = $r->{lib};
193 elsif ( $subfield->{authorised_value} eq "branches" ) {
194 push @authorised_values, "" if $default_branches_empty;
195 foreach my $thisbranch (@$libraries) {
196 push @authorised_values, $thisbranch->{branchcode};
197 $authorised_lib{ $thisbranch->{branchcode} } =
198 $thisbranch->{branchname};
199 $value = $thisbranch->{branchcode}
200 if $thisbranch->{selected} && !$value;
203 elsif ( $subfield->{authorised_value} eq "itemtypes" ) {
204 push @authorised_values, "";
207 $itemtypes = Koha::ItemTypes->search_with_localization(
208 { branchcode => $branch_limit } );
211 $itemtypes = Koha::ItemTypes->search_with_localization;
213 while ( my $itemtype = $itemtypes->next ) {
214 push @authorised_values, $itemtype->itemtype;
215 $authorised_lib{ $itemtype->itemtype } =
216 $itemtype->translated_description;
219 if (!$value && $biblionumber) {
220 my $itype_sth = $dbh->prepare(
221 "SELECT itemtype FROM biblioitems WHERE biblionumber = ?");
222 $itype_sth->execute($biblionumber);
223 ($value) = $itype_sth->fetchrow_array;
228 elsif ( $subfield->{authorised_value} eq "cn_source" ) {
229 push @authorised_values, "";
231 my $class_sources = GetClassSources();
233 C4::Context->preference("DefaultClassificationSource");
235 foreach my $class_source ( sort keys %$class_sources ) {
237 unless $class_sources->{$class_source}->{'used'}
238 or ( $value and $class_source eq $value )
239 or ( $class_source eq $default_source );
240 push @authorised_values, $class_source;
241 $authorised_lib{$class_source} =
242 $class_sources->{$class_source}->{'description'};
244 $value = $default_source if !$value && $prefill_with_default_values;
246 #---- "true" authorised value
249 push @authorised_values, qq{};
250 my $av = GetAuthorisedValues( $subfield->{authorised_value} );
252 push @authorised_values, $r->{authorised_value};
253 $authorised_lib{ $r->{authorised_value} } = $r->{lib};
257 if ( $subfield->{hidden} > 4 or $subfield->{hidden} <= -4 ) {
258 $subfield_data{marc_value} = {
260 id => $subfield_data{id},
261 maxlength => $subfield_data{maxlength},
265 grep { $_ eq $subfield->{authorised_value} }
266 (qw(branches itemtypes cn_source))
267 ) ? () : ( category => $subfield->{authorised_value} )
272 $subfield_data{marc_value} = {
279 values => \@authorised_values,
280 labels => \%authorised_lib,
284 grep { $_ eq $subfield->{authorised_value} }
285 (qw(branches itemtypes cn_source))
286 ) ? () : ( category => $subfield->{authorised_value} )
292 # it's a thesaurus / authority field
293 elsif ( $subfield->{authtypecode} ) {
294 $subfield_data{marc_value} = {
296 id => $subfield_data{id},
297 maxlength => $subfield_data{maxlength},
299 authtypecode => $subfield->{authtypecode},
303 # it's a plugin field
304 elsif ( $subfield->{value_builder} ) { # plugin
305 require Koha::FrameworkPlugin;
306 my $plugin = Koha::FrameworkPlugin->new(
308 name => $subfield->{'value_builder'},
314 record => $marc_record,
316 id => $subfield_data{id},
318 $plugin->build($pars);
319 if ( !$plugin->errstr ) {
320 my $class = 'buttonDot' . ( $plugin->noclick ? ' disabled' : '' );
321 $subfield_data{marc_value} = {
322 type => 'text_plugin',
323 id => $subfield_data{id},
324 maxlength => $subfield_data{maxlength},
327 nopopup => $plugin->noclick,
328 javascript => $plugin->javascript,
332 warn $plugin->errstr;
333 $subfield_data{marc_value} = {
335 id => $subfield_data{id},
336 maxlength => $subfield_data{maxlength},
338 }; # supply default input form
341 elsif ( $tag eq '' ) { # it's an hidden field
342 $subfield_data{marc_value} = {
344 id => $subfield_data{id},
345 maxlength => $subfield_data{maxlength},
349 elsif ( $subfield->{'hidden'} )
350 { # FIXME: shouldn't input type be "hidden" ?
351 $subfield_data{marc_value} = {
353 id => $subfield_data{id},
354 maxlength => $subfield_data{maxlength},
359 ( $value and length($value) > 100 )
360 or ( C4::Context->preference("marcflavour") eq "UNIMARC"
361 and 300 <= $tag && $tag < 400 && $subfieldtag eq 'a' )
362 or ( C4::Context->preference("marcflavour") eq "MARC21"
363 and 500 <= $tag && $tag < 600 )
366 # oversize field (textarea)
367 $subfield_data{marc_value} = {
369 id => $subfield_data{id},
374 # it's a standard field
375 $subfield_data{marc_value} = {
377 id => $subfield_data{id},
378 maxlength => $subfield_data{maxlength},
383 # Getting list of subfields to keep when restricted editing is enabled
384 # FIXME Improve the following block, no need to do it for every subfields
385 my $subfieldsToAllowForRestrictedEditing =
386 C4::Context->preference('SubfieldsToAllowForRestrictedEditing');
387 my $allowAllSubfields = (
388 not defined $subfieldsToAllowForRestrictedEditing
389 or $subfieldsToAllowForRestrictedEditing eq q||
391 my @subfieldsToAllow = split( / /, $subfieldsToAllowForRestrictedEditing );
393 # If we're on restricted editing, and our field is not in the list of subfields to allow,
394 # then it is read-only
395 $subfield_data{marc_value}->{readonly} =
396 ( not $allowAllSubfields
397 and $restricted_edition
398 and !grep { $tag . '$' . $subfieldtag eq $_ } @subfieldsToAllow )
402 return \%subfield_data;
406 Koha::UI::Form::Builder::Item->new(
407 { biblionumber => $biblionumber, item => $current_item } )->edit_form(
409 branchcode => $branchcode,
410 restricted_editition => $restrictededition,
412 @subfields_to_prefill
413 ? ( subfields_to_prefill => \@subfields_to_prefill )
416 prefill_with_default_values => 1,
417 branch_limit => C4::Context->userenv->{"branch"},
421 Returns the list of subfields to display on the add/edit item form.
423 Use it in the view with:
424 [% PROCESS subfields_for_item subfields => subfields %]
432 Pre-select a library (for logged in user)
434 =item restricted_editition
436 Flag to restrict the edition if the user does not have necessary permissions.
438 =item subfields_to_prefill
440 List of subfields to prefill (value of syspref SubfieldsToUseWhenPrefill)
442 =item subfields_to_allow
444 List of subfields to allow (value of syspref SubfieldsToAllowForRestrictedBatchmod)
446 =item subfields_to_ignore
448 List of subfields to ignore/skip
450 =item prefill_with_default_values
452 Flag to prefill with the default values defined in the framework.
456 Limit info depending on the library (so far only item types).
458 =item default_branches_empty
460 Flag to add an empty option to the library list.
467 my ( $self, $params ) = @_;
469 my $branchcode = $params->{branchcode};
470 my $restricted_edition = $params->{restricted_editition};
471 my $subfields_to_prefill = $params->{subfields_to_prefill} || [];
472 my $subfields_to_allow = $params->{subfields_to_allow} || [];
473 my $subfields_to_ignore= $params->{subfields_to_ignore} || [];
474 my $prefill_with_default_values = $params->{prefill_with_default_values};
475 my $branch_limit = $params->{branch_limit};
476 my $default_branches_empty = $params->{default_branches_empty};
479 Koha::Libraries->search( {}, { order_by => ['branchname'] } )->unblessed;
480 for my $library (@$libraries) {
481 $library->{selected} = 1 if $branchcode && $library->{branchcode} eq $branchcode;
484 my $item = $self->{item};
485 my $biblionumber = $self->{biblionumber};
486 my $frameworkcode = $biblionumber ? GetFrameworkCode($biblionumber) : q{};
487 my $marc_record = $biblionumber ? GetMarcBiblio( { biblionumber => $biblionumber } ) : undef;
489 my $tagslib = GetMarcStructure( 1, $frameworkcode );
490 foreach my $tag ( keys %{$tagslib} ) {
492 foreach my $subfieldtag ( keys %{ $tagslib->{$tag} } ) {
494 my $subfield = $tagslib->{$tag}{$subfieldtag};
496 next if IsMarcStructureInternal($subfield);
497 next if $subfield->{tab} ne "10";
498 next if @$subfields_to_allow && !grep { $subfield->{kohafield} eq $_ } @$subfields_to_allow;
500 if grep { $subfield->{kohafield} && $subfield->{kohafield} eq $_ }
501 @$subfields_to_ignore;
508 !@$subfields_to_prefill
509 || ( @$subfields_to_prefill && grep { $_ eq $subfieldtag }
510 @$subfields_to_prefill )
513 my $kohafield = $subfield->{kohafield};
516 # This is a mapped field
517 ( my $attribute = $kohafield ) =~ s|^items\.||;
518 push @values, $subfield->{repeatable}
519 ? split '\s\|\s', $item->{$attribute}
520 : $item->{$attribute}
521 if defined $item->{$attribute};
524 # Not mapped, picked the values from more_subfields_xml's MARC
525 my $marc_more = $item->{marc_more_subfields_xml};
527 for my $f ( $marc_more->fields($tag) ) {
528 push @values, $f->subfield($subfieldtag);
534 @values = ('') unless @values;
536 for my $value (@values) {
537 my $subfield_data = $self->generate_subfield_form(
540 subfieldtag => $subfieldtag,
543 libraries => $libraries,
544 marc_record => $marc_record,
545 restricted_edition => $restricted_edition,
546 prefill_with_default_values => $prefill_with_default_values,
547 branch_limit => $branch_limit,
548 default_branches_empty => $default_branches_empty,
551 push @subfields, $subfield_data;
557 $a->{display_order} <=> $b->{display_order}
558 || $a->{subfield} cmp $b->{subfield}