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>.
19 use Test::More tests => 9;
20 use Data::Dumper qw( Dumper );
23 use List::MoreUtils qw( uniq );
26 use Koha::MarcSubfieldStructures;
27 use Koha::UI::Form::Builder::Item;
28 use t::lib::TestBuilder;
31 my $schema = Koha::Database->new->schema;
32 $schema->storage->txn_begin;
34 my $builder = t::lib::TestBuilder->new;
36 my $cache = Koha::Caches->get_instance();
37 $cache->clear_from_cache("MarcStructure-0-");
38 $cache->clear_from_cache("MarcStructure-1-");
39 $cache->clear_from_cache("MarcSubfieldStructure-");
41 # 952 $x $é are not linked with a kohafield
42 # $952$x $é repeatable
43 # $952$t is not repeatable
44 # 952$z is linked with items.itemnotes and is repeatable
45 # 952$t is linked with items.copynumber and is not repeatable
48 # FIXME Later in this script we are comparing itemtypes, ordered by their description.
49 # MySQL and Perl don't sort _ identically.
50 # If you have one itemtype BK and another one B_K, MySQL will sort B_K first when Perl will sort it last
51 my @itemtypes = Koha::ItemTypes->search->as_list;
52 for my $itemtype ( @itemtypes ) {
53 my $d = $itemtype->description;
55 $itemtype->description($d)->store;
58 subtest 'authorised values' => sub {
61 my $biblio = $builder->build_sample_biblio({ value => {frameworkcode => ''}});
63 Koha::UI::Form::Builder::Item->new(
64 { biblionumber => $biblio->biblionumber } )->edit_form;
66 my @display_orders = uniq map { $_->{display_order} } @$subfields;
67 is_deeply( \@display_orders, [sort {$a <=> $b} @display_orders], 'subfields are sorted by display order' );
69 subtest 'normal AV' => sub {
72 grep { $_->{kohafield} eq 'items.notforloan' } @$subfields;
73 my $avs = Koha::AuthorisedValues->search( { category => 'NOT_LOAN' } );
76 $subfield->{marc_value}->{values},
79 map { $_->authorised_value }
80 sort { $a->lib cmp $b->lib }
83 'AVs are sorted by lib and en empty option is created first'
86 $subfield->{marc_value}->{labels},
88 map { $_->authorised_value => $_->lib }
89 sort { $a->lib cmp $b->lib }
95 subtest 'cn_source' => sub {
97 my ( $subfield ) = grep { $_->{kohafield} eq 'items.cn_source' } @$subfields;
98 is_deeply( $subfield->{marc_value}->{values}, [ '', 'ddc', 'lcc' ] );
100 $subfield->{marc_value}->{labels},
102 ddc => "Dewey Decimal Classification",
103 lcc => "Library of Congress Classification",
107 subtest 'branches' => sub {
109 my ( $subfield ) = grep { $_->{kohafield} eq 'items.homebranch' } @$subfields;
110 my $libraries = Koha::Libraries->search({}, { order_by => 'branchname' });
112 $subfield->{marc_value}->{values},
113 [ $libraries->get_column('branchcode') ]
116 $subfield->{marc_value}->{labels},
117 { map { $_->branchcode => $_->branchname } $libraries->as_list }
121 subtest 'itemtypes' => sub {
123 my ($subfield) = grep { $_->{kohafield} eq 'items.itype' } @$subfields;
124 my @itemtypes = Koha::ItemTypes->search->as_list;
129 # We need to sort using uc or perl won't be case insensitive
130 sort { uc($a->translated_description) cmp uc($b->translated_description) }
134 $subfield->{marc_value}->{values},
136 "Item types should be sorted by description and an empty entry should be shown"
139 is_deeply( $subfield->{marc_value}->{labels},
140 { map { $_->itemtype => $_->description } @itemtypes},
141 'Labels should be correctly displayed'
146 subtest 'prefill_with_default_values' => sub {
149 my $biblio = $builder->build_sample_biblio({ value => {frameworkcode => ''}});
151 Koha::UI::Form::Builder::Item->new(
152 { biblionumber => $biblio->biblionumber } )->edit_form;
155 my ($subfield) = grep { $_->{subfield} eq 'é' } @$subfields;
156 is( $subfield->{marc_value}->{value}, '', 'no default value if prefill_with_default_values not passed' );
159 Koha::UI::Form::Builder::Item->new(
160 { biblionumber => $biblio->biblionumber } )->edit_form({ prefill_with_default_values => 1 });
163 ($subfield) = grep { $_->{subfield} eq 'é' } @$subfields;
164 is( $subfield->{marc_value}->{value}, 'ééé', 'default value should be set if prefill_with_default_values passed');
166 # Do the same for an existing item; we do not expect the defaultvalue to popup
167 my $item = $builder->build_sample_item;
168 $subfields = Koha::UI::Form::Builder::Item->new({
169 biblionumber => $biblio->biblionumber,
170 item => $item->unblessed,
171 })->edit_form({ prefill_with_default_values => 1 });
172 ($subfield) = grep { $_->{subfield} eq 'é' } @$subfields;
173 is( $subfield->{marc_value}->{value}, q{}, 'default value not applied to existing item');
177 subtest 'subfields_to_prefill' => sub {
180 my $biblio = $builder->build_sample_biblio({ value => {frameworkcode => ''}});
182 my $more_subfields_xml = Koha::Item::Attributes->new({ "é" => "prefill é" })->to_marcxml;
184 Koha::UI::Form::Builder::Item->new(
185 { biblionumber => $biblio->biblionumber, item => {more_subfields_xml => $more_subfields_xml}})->edit_form({subfields_to_prefill => ['é']});
186 my ($subfield) = grep { $_->{subfield} eq 'é' } @$subfields;
187 is( $subfield->{marc_value}->{value}, 'prefill é', 'Not mapped subfield prefilled if needed' );
190 Koha::UI::Form::Builder::Item->new(
191 { biblionumber => $biblio->biblionumber, item => {itemnotes => 'prefill z'}})->edit_form({subfields_to_prefill => ['z']});
192 ($subfield) = grep { $_->{subfield} eq 'z' } @$subfields;
193 is( $subfield->{marc_value}->{value}, 'prefill z', 'Mapped subfield prefilled if needed');
196 subtest 'branchcode' => sub {
199 my $biblio = $builder->build_sample_biblio({ value => {frameworkcode => ''}});
200 my $library = $builder->build_object({ class => 'Koha::Libraries' });
202 Koha::UI::Form::Builder::Item->new(
203 { biblionumber => $biblio->biblionumber } )->edit_form;
205 my ( $subfield ) = grep { $_->{kohafield} eq 'items.homebranch' } @$subfields;
206 is( $subfield->{marc_value}->{default}, '', 'no library preselected if no branchcode passed');
209 Koha::UI::Form::Builder::Item->new(
210 { biblionumber => $biblio->biblionumber } )->edit_form({ branchcode => $library->branchcode });
212 ( $subfield ) = grep { $_->{kohafield} eq 'items.homebranch' } @$subfields;
213 is( $subfield->{marc_value}->{default}, $library->branchcode, 'the correct library should be preselected if branchcode is passed');
216 subtest 'default_branches_empty' => sub {
219 my $biblio = $builder->build_sample_biblio({ value => {frameworkcode => ''}});
221 Koha::UI::Form::Builder::Item->new(
222 { biblionumber => $biblio->biblionumber } )->edit_form;
224 my ( $subfield ) = grep { $_->{kohafield} eq 'items.homebranch' } @$subfields;
225 isnt( $subfield->{marc_value}->{values}->[0], "", 'No empty option for branches' );
228 Koha::UI::Form::Builder::Item->new(
229 { biblionumber => $biblio->biblionumber } )->edit_form({ default_branches_empty => 1 });
231 ( $subfield ) = grep { $_->{kohafield} eq 'items.homebranch' } @$subfields;
232 is( $subfield->{marc_value}->{values}->[0], "", 'empty option for branches if default_branches_empty passed' );
235 subtest 'kohafields_to_ignore' => sub {
239 $builder->build_sample_biblio( { value => { frameworkcode => '' } } );
241 Koha::UI::Form::Builder::Item->new(
242 { biblionumber => $biblio->biblionumber } )->edit_form;
244 my ($subfield) = grep { $_->{kohafield} eq 'items.barcode' } @$subfields;
245 isnt( $subfield, undef, 'barcode subfield should be in the subfield list' );
248 Koha::UI::Form::Builder::Item->new(
249 { biblionumber => $biblio->biblionumber } )
250 ->edit_form( { kohafields_to_ignore => ['items.barcode'] } );
252 ($subfield) = grep { $_->{kohafield} eq 'items.barcode' } @$subfields;
253 is( $subfield, undef,
254 'barcode subfield should have not been built if passed to kohafields_to_ignore'
258 subtest 'subfields_to_allow & ignore_not_allowed_subfields' => sub {
261 my ( $tag_cn, $subtag_cn ) = C4::Biblio::GetMarcFromKohaField("items.itemcallnumber");
262 my ( $tag_notes, $subtag_notes ) = C4::Biblio::GetMarcFromKohaField("items.itemnotes");
263 my $biblio = $builder->build_sample_biblio( { value => { frameworkcode => '' } } );
265 Koha::UI::Form::Builder::Item->new(
266 { biblionumber => $biblio->biblionumber } )->edit_form(
268 subfields_to_allow => [
269 sprintf( '%s$%s', $tag_cn, $subtag_cn ),
270 sprintf( '%s$%s', $tag_notes, $subtag_notes )
275 isnt( scalar(@$subfields), 2, "There are more than the 2 subfields we allowed" );
276 my ($subfield) = grep { $_->{kohafield} eq 'items.itemcallnumber' } @$subfields;
277 is( $subfield->{marc_value}->{readonly}, undef, "subfields to allowed are not marked as readonly" );
278 ($subfield) = grep { $_->{kohafield} eq 'items.copynumber' } @$subfields;
279 isnt( $subfield->{marc_value}->{readonly}, 1, "subfields that are not in the allow list are marked as readonly" );
282 Koha::UI::Form::Builder::Item->new(
283 { biblionumber => $biblio->biblionumber } )->edit_form(
285 subfields_to_allow => [
286 sprintf( '%s$%s', $tag_cn, $subtag_cn ),
287 sprintf( '%s$%s', $tag_notes, $subtag_notes )
289 ignore_not_allowed_subfields => 1,
293 is( scalar(@$subfields), 2, "With ignore_not_allowed_subfields, only the subfields to ignore are returned" );
295 grep { $_->{kohafield} eq 'items.itemcallnumber' } @$subfields;
296 is( $subfield->{marc_value}->{readonly}, undef, "subfields to allowed are not marked as readonly" );
297 ($subfield) = grep { $_->{kohafield} eq 'items.copynumber' } @$subfields;
298 is( $subfield, undef, "subfield that is not in the allow list is not returned" );
301 subtest 'ignore_invisible_subfields' => sub {
305 $builder->build_sample_biblio( { value => { frameworkcode => '' } } );
306 my $item = $builder->build_sample_item(
312 # items.issues is mapped with 952$l
313 my $subfields = Koha::UI::Form::Builder::Item->new(
315 biblionumber => $biblio->biblionumber,
316 item => $item->unblessed,
319 ( my $subfield ) = grep { $_->{subfield} eq 'l' } @$subfields;
320 is( $subfield->{marc_value}->{value}, 42, 'items.issues copied' );
322 $subfields = Koha::UI::Form::Builder::Item->new(
324 biblionumber => $biblio->biblionumber,
325 item => $item->unblessed,
329 ignore_invisible_subfields => 1
332 ($subfield) = grep { $_->{subfield} eq 'l' } @$subfields;
333 is( $subfield->{marc_value}->{value},
334 undef, 'items.issues not copied if ignore_invisible_subfields is passed' );
337 subtest 'Fix subfill_with_default_values - no biblionumber passed' => sub {
340 t::lib::Mocks::mock_preference('itemcallnumber', '082ab,092ab');
341 my $item = $builder->build_sample_item;
342 my $subfields = Koha::UI::Form::Builder::Item->new(
344 item => $item->unblessed,
346 )->edit_form({ prefill_with_default_values => 1 });
350 $cache->clear_from_cache("MarcStructure-0-");
351 $cache->clear_from_cache("MarcStructure-1-");
352 $cache->clear_from_cache("MarcSubfieldStructure-");
356 my ( $itemtag, $itemsubfield ) = C4::Biblio::GetMarcFromKohaField( "items.itemnumber" );
358 Koha::MarcSubfieldStructures->search(
361 tagfield => $itemtag,
364 )->delete; # In case it exist already
366 Koha::MarcSubfieldStructure->new(
369 tagfield => $itemtag,
373 defaultvalue => 'ééé',
378 Koha::MarcSubfieldStructures->search(
381 tagfield => $itemtag,
382 tagsubfield => [ 'x' ]
384 )->update( { kohafield => undef } );
386 Koha::MarcSubfieldStructures->search(
389 tagfield => $itemtag,
390 tagsubfield => [ 'x', 'é' ],
392 )->update( { repeatable => 1 } );
394 Koha::MarcSubfieldStructures->search(
397 tagfield => $itemtag,
398 tagsubfield => ['t'],
400 )->update( { repeatable => 0 } );
402 Koha::MarcSubfieldStructures->search(
405 tagfield => $itemtag,
406 tagsubfield => ['l'],
408 )->update( { hidden => -4 } );
410 Koha::MarcSubfieldStructures->search(
413 tagfield => $itemtag,
414 tagsubfield => ['z'],
416 )->update( { kohafield => 'items.itemnotes', repeatable => 1 } );
418 Koha::MarcSubfieldStructures->search(
421 tagfield => $itemtag,
423 )->update( { display_order => \['FLOOR( 1 + RAND( ) * 10 )'] } );