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