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 |
- |
|
|