5 # Copyright 2000-2002 Katipo Communications
7 # This file is part of Koha.
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along with
19 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 # Suite 330, Boston, MA 02111-1307 USA
26 use C4::Interface::CGI::Output;
29 use C4::Koha; # XXX subfield_is_koha_internal_p
31 use C4::Circulation::Circ2;
35 my $logstatus=C4::Context->preference('Activate_log');
38 my ($tagfield,$insubfield,$record) = @_;
41 my $item=$record->{datafield};
42 my $controlfield=$record->{controlfield};
43 my $leader=$record->{leader};
44 if ($tagfield eq '000'){
45 ## We are getting the leader
47 return($indicator,$result);
50 foreach my $control (@$controlfield) {
51 if ($control->{tag} eq $tagfield){
52 $result.=$control->{content};
56 foreach my $field (@$item) {
57 if ($field->{tag} eq $tagfield){
58 foreach my $subfield ( $field->{'subfield'}){
59 foreach my $code ( @$subfield){
60 if ($code->{code} eq $insubfield) {
61 $result .= $code->{content};
62 $indicator = $field->{ind1}.$field->{ind2};
69 return($indicator,$result);
72 my $dbh = C4::Context->dbh;
73 my $error = $input->param('error');
74 my $biblionumber = $input->param('biblionumber');
75 my $oldbiblionumber =$biblionumber;
76 my $frameworkcode=$input->param('frameworkcode');
77 my $op = $input->param('op');
78 my $itemnumber = $input->param('itemnumber');
79 my $fromserials=$input->param('fromserials');## if a serial is being added do not display navigation menus
80 my $serialid=$input->param('serialid');
81 my @itemrecords; ##Builds existing items
82 my $bibliorecord; #Bibliorecord relared to this item
83 my $newrecord; ## the new record buing built
84 my $itemrecexist; #item record we are editing
85 my $xml; ## data on html
86 $frameworkcode=MARCfind_frameworkcode($dbh,$biblionumber) unless $frameworkcode;
87 my $tagslib = &MARCitemsgettagslib($dbh,1,$frameworkcode);
90 my @errors; # store errors found while checking data BEFORE saving item.
92 ###DO NOT CHANGE TO RETRIVE FROM ZEBRA#####
93 my $record =XMLgetbiblio($dbh,$biblionumber);
94 $bibliorecord=XML_xml2hash_onerecord($record);
95 my @itemxmls=XMLgetallitems($dbh,$biblionumber);
96 foreach my $itemrecord(@itemxmls){
97 my $itemhash=XML_xml2hash($itemrecord);
98 push @itemrecords, $itemhash;
102 my ($template, $loggedinuser, $cookie)
103 = get_template_and_user({template_name => "cataloguing/additem.tmpl",
106 authnotrequired => 0,
107 flagsrequired => {editcatalogue => 1},
111 #------------------------------------------------------------------------------------------------------------------------------
112 if ($op eq "additem") {
113 #------------------------------------------------------------------------------------------------------------------------------
116 my @tags = $input->param('tag');
117 my @subfields = $input->param('subfield');
118 my @values = $input->param('field_value');
119 # build indicator hash.
120 my @ind_tag = $input->param('ind_tag');
121 my @indicator = $input->param('indicator');
123 for (my $i=0;$i<=$#ind_tag;$i++) {
124 $indicators{$ind_tag[$i]} = $indicator[$i];
126 ## check for malformed xml -- non UTF-8 like (MARC8) will break xml without warning
127 ### This usually happens with data coming from other Z3950 servers
128 ## Slows the saving process so comment out at your own risk
130 $xml = MARChtml2xml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag);
133 push @errors,"non_utf8" ;
137 my $newrecord=XML_xml2hash_onerecord($xml);
138 my $newbarcode=XML_readline_onerecord($newrecord,"barcode","holdings");
140 # if autoBarcode is ON, calculate barcode...
141 if (C4::Context->preference('autoBarcode')) {
142 unless ($newbarcode) {
143 my $sth_barcode = $dbh->prepare("select max(abs(barcode)) from items");
144 $sth_barcode->execute;
145 ($newbarcode) = $sth_barcode->fetchrow;
147 # OK, we have the new barcode, now create the entry in MARC record
148 $newrecord=XML_writeline( $newrecord, "barcode", $newbarcode,"holdings" );
151 # check for item barcode # being unique
152 my ($oldrecord)=XMLgetitem($dbh,"",$newbarcode);
154 push @errors,"barcode_not_unique" if($oldrecord);
155 # MARC::Record builded => now, record in DB
156 ## User may be keeping serialids in marc records -- check and add it
158 $newrecord=XML_writeline( $newrecord, "serialid", $serialid,"holdings" );
160 # if barcode exists, don't create, but report the problem.
162 $itemnumber=NEWnewitem($dbh,$newrecord,$biblionumber) ;
164 my $holdingbranch=XML_readline_onerecord($newrecord,"holdingbranch","holdings");
165 $template->param(exit=>1,holdingbranch=>$holdingbranch);
171 $itemrecexist = $newrecord;
173 #------------------------------------------------------------------------------------------------------------------------------
174 } elsif ($op eq "edititem") {
175 #------------------------------------------------------------------------------------------------------------------------------
176 # retrieve item if exist => then, it's a modif
177 ($itemrecexist) = XMLfinditem($itemnumber,@itemrecords);## item is already in our array-getit
180 #logaction($loggedinuser,"acqui.simple","modify",$oldbiblionumber,"item : ".$itemnumber) if ($logstatus);
182 #------------------------------------------------------------------------------------------------------------------------------
183 } elsif ($op eq "delitem") {
184 #------------------------------------------------------------------------------------------------------------------------------
185 # retrieve item if exist => then, it's a modif
186 my $sth=$dbh->prepare("select * from issues i where i.returndate is null and i.itemnumber=?");
187 $sth->execute($itemnumber);
188 my $onloan=$sth->fetchrow;
189 push @errors,"book_on_loan" if ($onloan);
193 &NEWdelitem($dbh,$itemnumber);
196 #------------------------------------------------------------------------------------------------------------------------------
197 } elsif ($op eq "saveitem") {
198 #------------------------------------------------------------------------------------------------------------------------------
201 my @tags = $input->param('tag');
202 my @subfields = $input->param('subfield');
203 my @values = $input->param('field_value');
204 # build indicator hash.
205 my @ind_tag = $input->param('ind_tag');
206 my @indicator = $input->param('indicator');
207 my $itemnumber = $input->param('itemnumber');
209 for (my $i=0;$i<=$#ind_tag;$i++) {
210 $indicators{$ind_tag[$i]} = $indicator[$i];
212 ## check for malformed xml -- non UTF-8 like (MARC8) will break xml without warning
213 ### This usually happens with data coming from other Z3950 servers
214 ## Slows the saving process so comment out at your own risk
216 $xml = MARChtml2xml(\@tags,\@subfields,\@values,\@indicator,\@ind_tag);
219 push @errors,"non_utf8" ;
220 $nextop = "edititem";
223 my $newrecord=XML_xml2hash_onerecord($xml);
224 my $newbarcode=XML_readline_onerecord($newrecord,"barcode","holdings");
225 my ($oldrecord)=XMLgetitem($dbh,"",$newbarcode);
226 $oldrecord=XML_xml2hash_onerecord($oldrecord);
227 my $exist=XML_readline_onerecord($oldrecord,"itemnumber","holdings") if $oldrecord;
228 if ($exist && ($exist ne $itemnumber)){
229 push @errors,"barcode_not_unique" ; ## Although editing user may have changed the barcode
232 NEWmoditem($dbh,$newrecord,$biblionumber,$itemnumber);
240 #------------------------------------------------------------------------------------------------------------------------------
241 # build screen with existing items. and "new" one
242 #------------------------------------------------------------------------------------------------------------------------------
245 $indicators{995}=' ';
246 # now, build existing item list
250 my ($itemtagfield,$itemtagsubfield) = &MARCfind_marc_from_kohafield("itemnumber","holdings");
253 my %witness; #---- stores the list of subfields used at least once, with the "meaning" of the code
256 my @header_value_loop;
257 unless($fromserials){ ## do not display existing items if adding a serial. It could be a looong list
258 foreach my $itemrecord (@itemrecords){
260 my $item=$itemrecord->{datafield};
261 my $controlfield=$itemrecord->{controlfield};
262 my $leader=$itemrecord->{leader};
265 unless ($tagslib->{'000'}->{'@'}->{tab} ne 10 || substr($tagslib->{'000'}->{'@'}->{hidden},1,1)>0){
267 $witness{$datasub[0]} = $tagslib->{'000'}->{'@'}->{lib};
268 $this_row{$datasub[0]} =$leader->[0];
270 foreach my $control (@$controlfield){
271 push @itemnums,$control->{content} if ($control->{tag} eq $itemtagfield);
272 next if ($tagslib->{$control->{tag}}->{'@'}->{tab} ne 10);
273 next if (substr($tagslib->{$control->{tag}}->{'@'}->{hidden},1,1)>0);
275 my @datasub=$control->{tag}.'@';
276 $witness{$datasub[0]} = $tagslib->{$control->{tag}}->{'@'}->{lib};
277 $this_row{$datasub[0]} =$control->{content};
279 foreach my $data (@$item){
280 foreach my $subfield ( $data->{'subfield'}){
281 foreach my $code ( @$subfield){
282 # loop through each subfield
283 push @itemnums,$code->{content} if ($data->{tag} eq $itemtagfield && $code->{code} eq $itemtagsubfield);
284 next if ($tagslib->{$data->{tag}}->{$code->{code}}->{tab} ne 10);
285 next if (substr($tagslib->{$data->{tag}}->{$code->{code}}->{hidden},1,1)>0);
286 $witness{$data->{tag}.$code->{code}} = $tagslib->{$data->{tag}}->{$code->{code}}->{lib};
287 $this_row{$data->{tag}.$code->{code}} =$code->{content};
294 push(@big_array, \%this_row);
297 #fill big_row with missing datas
298 foreach my $subfield_code (keys(%witness)) {
299 for (my $i=0;$i<=$#big_array;$i++) {
300 $big_array[$i]{$subfield_code}=" " unless ($big_array[$i]{$subfield_code});
303 # now, construct template !
305 for (my $i=0;$i<=$#big_array; $i++) {
307 foreach my $subfield_code (sort keys(%witness)) {
308 $items_data .="<td>".$big_array[$i]{$subfield_code}."</td>";
311 $row_data{item_value} = $items_data;
312 $row_data{itemnumber} = $itemnums[$i];
313 push(@item_value_loop,\%row_data);
315 foreach my $subfield_code (sort keys(%witness)) {
317 $header_value{header_value} = $witness{$subfield_code};
318 push(@header_value_loop, \%header_value);
320 }## unless from serials
324 my $authorised_values_sth = $dbh->prepare("select authorised_value,lib from authorised_values where category=? order by lib");
326 foreach my $tag (sort keys %{$tagslib}) {
327 if ($itemtagfield <10){
328 next if($tag==$itemtagfield);
330 my $previous_tag = '';
331 # loop through each subfield
332 foreach my $subfield (sort keys %{$tagslib->{$tag}}) {
333 next if subfield_is_koha_internal_p($subfield);
334 next if ($tagslib->{$tag}->{$subfield}->{'tab'} ne "10");
335 next if ($tagslib->{$tag} eq $itemtagfield && $tagslib->{$tag}->{$subfield} eq $itemtagsubfield);
337 $subfield_data{tag}=$tag;
338 $subfield_data{subfield}=$subfield;
339 $subfield_data{marc_lib}="<span id=\"error$i\">".$tagslib->{$tag}->{$subfield}->{lib}."</span>";
340 $subfield_data{mandatory}=$tagslib->{$tag}->{$subfield}->{mandatory};
341 $subfield_data{repeatable}=$tagslib->{$tag}->{$subfield}->{repeatable};
342 $subfield_data{hidden}= "display:none" if (substr($tagslib->{$tag}->{$subfield}->{hidden},2,1)>0);
345 ($x,$value) = find_value($tag,$subfield,$itemrecexist) if ($itemrecexist);
346 # search for itemcallnumber if applicable
347 my ($itemcntag,$itemcntagsub)=MARCfind_marc_from_kohafield("itemcallnumber","holdings");
348 if ($tag eq $itemcntag && $subfield eq $itemcntagsub && C4::Context->preference('itemcallnumber')) {
349 my $CNtag = substr(C4::Context->preference('itemcallnumber'),0,3);
350 my $CNsubfield = substr(C4::Context->preference('itemcallnumber'),3,1);
351 my $CNsubfield2 = substr(C4::Context->preference('itemcallnumber'),4,1);
352 my $temp1 = XML_readline_onerecord($bibliorecord,"","",$CNtag,$CNsubfield);
353 my $temp2 = XML_readline_onerecord($bibliorecord,"","",$CNtag,$CNsubfield2);
354 $value = $temp1.' '.$temp2;
355 $value=~s/^\s+|\s+$//g;
358 if ($tagslib->{$tag}->{$subfield}->{authorised_value}) {
359 my @authorised_values;
361 # builds list, depending on authorised value...
363 if ($tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
364 my $sth=$dbh->prepare("select branchcode,branchname from branches order by branchname");
366 push @authorised_values, "" unless ($tagslib->{$tag}->{$subfield}->{mandatory});
367 while (my ($branchcode,$branchname) = $sth->fetchrow_array) {
368 push @authorised_values, $branchcode;
369 $authorised_lib{$branchcode}=$branchname;
372 } elsif ($tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes") {
373 my $sth=$dbh->prepare("select itemtype,description from itemtypes order by description");
375 push @authorised_values, "" unless ($tagslib->{$tag}->{$subfield}->{mandatory});
376 while (my ($itemtype,$description) = $sth->fetchrow_array) {
377 push @authorised_values, $itemtype;
378 $authorised_lib{$itemtype}=$description;
380 #---- "true" authorised value
382 $authorised_values_sth->execute($tagslib->{$tag}->{$subfield}->{authorised_value});
383 push @authorised_values, "" unless ($tagslib->{$tag}->{$subfield}->{mandatory});
384 while (my ($value,$lib) = $authorised_values_sth->fetchrow_array) {
385 push @authorised_values, $value;
386 $authorised_lib{$value}=$lib;
389 $subfield_data{marc_value}= CGI::scrolling_list(-name=>'field_value',
390 -values=> \@authorised_values,
391 -default=>"$value", -labels => \%authorised_lib, -size=>1,
393 } elsif ($tagslib->{$tag}->{$subfield}->{thesaurus_category}) {
394 $subfield_data{marc_value}="<input type=\"text\" name=\"field_value\" size=47 maxlength=255 DISABLE READONLY> <a href=\"javascript:Dopop('../authorities/auth_finder.pl?authtypecode=".$tagslib->{$tag}->{$subfield}->{authtypecode}."&index=$i',$i)\">...</a>";
396 } elsif ($tagslib->{$tag}->{$subfield}->{'value_builder'}) {
397 my $cgidir = C4::Context->intranetdir ."/cgi-bin/value_builder";
398 unless (opendir(DIR, "$cgidir")) {
399 $cgidir = C4::Context->intranetdir."/value_builder";
401 my $plugin=$cgidir."/".$tagslib->{$tag}->{$subfield}->{'value_builder'};
403 my $extended_param = plugin_parameters($dbh,$newrecord,$tagslib,$i,0);
404 my ($function_name,$javascript) = plugin_javascript($dbh,$newrecord,$tagslib,$i,0);
405 $subfield_data{marc_value}="<input type=\"text\" name=\"field_value\" value=\"$value\" size=\"47\" maxlength=\"255\" DISABLE READONLY OnFocus=\"javascript:Focus$function_name($i)\" OnBlur=\"javascript:Blur$function_name($i)\"> <a href=\"javascript:Clic$function_name($i)\">...</a> $javascript";
407 $subfield_data{marc_value}="<input type=\"text\" name=\"field_value\" value=\"$value\" size=50 maxlength=255>";
409 # $subfield_data{marc_value}="<input type=\"text\" name=\"field_value\">";
410 push(@loop_data, \%subfield_data);
416 # what's the next op ? it's what we are not in : an add if we're editing, otherwise, and edit.
417 $template->param(item_loop => \@item_value_loop,
418 item_header_loop => \@header_value_loop,
419 biblionumber =>$biblionumber,
420 title => &XML_readline_onerecord($bibliorecord,"title","biblios"),
421 author => &XML_readline_onerecord($bibliorecord,"author","biblios"),
423 itemnumber => $itemnumber,
424 itemtagfield => $itemtagfield,
425 itemtagsubfield =>$itemtagsubfield,
427 opisadd => ($nextop eq "saveitem")?0:1,
428 fromserials=>$fromserials, serialid=>$serialid,);
429 foreach my $error (@errors) {
430 $template->param($error => 1);
433 output_html_with_http_headers $input, $cookie, $template->output;
436 my ($itemnumber,@itemrecords)=@_;
437 foreach my $record (@itemrecords){
438 my $inumber=XML_readline_onerecord($record,"itemnumber","holdings");
439 if ($inumber ==$itemnumber){