moving z3950 related scripts to specific dir
[koha.git] / z3950 / z3950import.pl
1 #!/usr/bin/perl
2
3 # $Id$
4
5 # Script for handling import of MARC data into Koha db
6 #   and Z39.50 lookups
7
8 # Koha library project  www.koha.org
9
10 # Licensed under the GPL
11
12
13 # Copyright 2000-2002 Katipo Communications
14 #
15 # This file is part of Koha.
16 #
17 # Koha is free software; you can redistribute it and/or modify it under the
18 # terms of the GNU General Public License as published by the Free Software
19 # Foundation; either version 2 of the License, or (at your option) any later
20 # version.
21 #
22 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
23 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
24 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
25 #
26 # You should have received a copy of the GNU General Public License along with
27 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
28 # Suite 330, Boston, MA  02111-1307 USA
29
30 use strict;
31
32 # standard or CPAN modules used
33 use CGI;
34 use DBI;
35
36 # Koha modules used
37 use C4::Context;
38 use C4::Database;
39 use C4::Acquisitions;
40 use C4::Output;
41 use C4::Input;
42 use C4::Biblio;
43 use C4::SimpleMarc;
44 use C4::Z3950;
45 use MARC::File::USMARC;
46 use HTML::Template;
47
48 #------------------
49 # Constants
50
51 my $includes = C4::Context->config('includes') ||
52         "/usr/local/www/hdl/htdocs/includes";
53
54 # HTML colors for alternating lines
55 my $lc1='#dddddd';
56 my $lc2='#ddaaaa';
57
58 #-------------
59 #-------------
60 # Initialize
61
62 my $userid=$ENV{'REMOTE_USER'};
63
64 my $input = new CGI;
65 my $dbh = C4::Context->dbh;
66
67 #-------------
68 # Display output
69 #print $input->header;
70 #print startpage();
71 #print startmenu('acquisitions');
72
73 #-------------
74 # Process input parameters
75
76 my $file=$input->param('file');
77 my $menu = $input->param('menu');
78
79 #
80 #
81 # TODO : parameter decoding and function call is quite dirty.
82 # should be rewritten...
83 #
84 #
85 if ($input->param('z3950queue')) {
86         AcceptZ3950Queue($dbh,$input);
87 }
88
89 if ($input->param('uploadmarc')) {
90         AcceptMarcUpload($dbh,$input)
91 }
92
93 if ($input->param('insertnewrecord')) {
94     # Add biblio item, and set up menu for adding item copies
95     my ($biblionumber,$biblioitemnumber)=AcceptBiblioitem($dbh,$input);
96     exit;
97 }
98
99 if ($input->param('newitem')) {
100     # Add item copy
101     &AcceptItemCopy($dbh,$input);
102     exit;
103 } # if newitem
104
105
106 if ($file) {
107     ProcessFile($dbh,$input);
108 } else {
109   SWITCH:
110     {
111         if ($menu eq 'z3950') { z3950menu($dbh,$input); last SWITCH; }
112         if ($menu eq 'uploadmarc') { uploadmarc($dbh); last SWITCH; }
113         if ($menu eq 'manual') { manual(); last SWITCH; }
114         mainmenu();
115     }
116 }
117 #print endmenu();
118 #print endpage();
119
120
121 # Process a MARC file : show list of records, of 1 record detail, if numrecord exists
122 sub ProcessFile {
123     # A MARC file has been specified; process it for review form
124     use strict;
125     # Input params
126     my (
127         $dbh,           # FIXME - Unused argument
128         $input,
129     )=@_;
130
131     # local vars
132     my (
133         $sth,
134         $record,
135     );
136
137     my $debug=0;
138
139     $dbh = C4::Context->dbh;
140
141     # See if a particular result item was specified
142     my $numrecord = $input->param('numrecord');
143     if ($numrecord) {
144         ProcessRecord($dbh,$input,$numrecord);
145     } else {
146         # No result item specified, list results
147         ListFileRecords($dbh,$input);
148     } # if
149 } # sub ProcessFile
150
151 # show 1 record from the MARC file
152 sub ProcessRecord {
153     my ($dbh, $input,$numrecord) = @_;
154     # local vars
155     my (
156         $sth,
157         $record,
158         $data,
159     );
160
161     if ($file=~/Z-(\d+)/) {
162         my $id=$1;
163         my $resultsid=$input->param('resultsid');
164         my $sth=$dbh->prepare("select results from z3950results where id=$resultsid");
165         $sth->execute;
166         ($data) = $sth->fetchrow;
167     } else {
168         my $sth=$dbh->prepare("select marc from uploadedmarc where id=$file");
169         $sth->execute;
170         ($data) = $sth->fetchrow;
171     }
172
173     my $file=MARC::File::USMARC->indata ($data);
174     my $oldkoha;
175     # FIXME - This "==" should be "=", right?
176     for (my $i==1;$i<$numrecord;$i++) {
177         $record = $file->next;
178     }
179     if ($record) {
180         $oldkoha=MARCmarc2koha($dbh,$record);
181     }
182     my $template=gettemplate('marcimport/marcimportdetail.tmpl');
183     $oldkoha->{additionalauthors} =~ s/ \| /\n/g;
184     $oldkoha =~ s/\|/\n/g;
185     $template->param($oldkoha);
186 #---- build MARC array for template
187     my @loop = ();
188     my $tagmeaning = &MARCgettagslib($dbh,1);
189     my @fields = $record->fields();
190     my $color=0;
191     my $lasttag="";
192     foreach my $field (@fields) {
193         my @subfields=$field->subfields();
194         foreach my $subfieldcount (0..$#subfields) {
195             my %row_data;
196             if ($lasttag== $field->tag()) {
197                 $row_data{tagid}   = "";
198             } else {
199                 $row_data{tagid}   = $field->tag();
200             }
201             $row_data{subfield} = $subfields[$subfieldcount][0];
202             $row_data{tagmean} = $tagmeaning->{$field->tag()}->{$subfields[$subfieldcount][0]};
203             $row_data{tagvalue}= $subfields[$subfieldcount][1];
204             if ($color ==0) {
205                 $color=1;
206                 $row_data{color} = $lc1;
207             } else {
208                 $color=0;
209                 $row_data{color} = $lc2;
210             }
211             push(@loop,\%row_data);
212             $lasttag=$field->tag();
213         }
214     }
215     $template->param(MARC => \@loop);
216     $template->param(numrecord => $numrecord);
217     $template->param(file => $data);
218     print "Content-Type: text/html\n\n", $template->output;
219 }
220
221 # lists all records from the MARC file
222 sub ListFileRecords {
223     use strict;
224
225     # Input parameters
226     my (
227         $dbh,           # FIXME - Unused argument
228         $input,
229     )=@_;
230
231     my (
232         $sth, $sti,
233         $field,
234         $data,          # records in MARC file format
235         $name,
236         $srvid,
237         %servernames,
238         $serverdb,
239     );
240
241     my $z3950=0;
242     my $recordsource;
243     my $record;
244     my ($numrecords,$resultsid,$data,$startdate,$enddate);
245                 # FIXME - there's already a $data a few lines above.
246
247     $dbh = C4::Context->dbh;
248
249     my $template=gettemplate('marcimport/ListFileRecords.tmpl');
250     # File can be z3950 search query or uploaded MARC data
251
252     # if z3950 results
253     if (not $file=~/Z-(\d+)/) {
254         # This is a Marc upload
255         $sth=$dbh->prepare("select marc,name from uploadedmarc where id=$file");
256         $sth->execute;
257         ($data, $name) = $sth->fetchrow;
258         $template->param(IS_MARC => 1);
259         $template->param(recordsource => $name);
260     }
261
262     if ($file=~/Z-(\d+)/) {
263         # This is a z3950 search
264         $template->param(IS_Z3950 =>1);
265         my $id=$1;              # search query id number
266         my $serverstring;
267         my $starttimer=time();
268
269         $sth=$dbh->prepare("
270                 select z3950results.numrecords,z3950results.id,z3950results.results,
271                         z3950results.startdate,z3950results.enddate,server
272                 from z3950queue left outer join z3950results
273                      on z3950queue.id=z3950results.queryid
274                 where z3950queue.id=?
275                 order by server
276             ");
277         $sth->execute($id);
278         if ( $sth->rows ) {
279             # loop through all servers in search results
280             while ( ($numrecords,$resultsid,$data,
281                      $startdate,$enddate,$serverstring) = $sth->fetchrow ) {
282                 my ($srvid, $server, $database, $auth) = split(/\//, $serverstring, 4);
283                 if ( $server ) {
284                         my $srvname=&z3950servername($dbh,$srvid,"$server/$database");
285                         $template->param(srvid => $srvid);
286                         $template->param(srvname => $srvname);
287                 } # if $server
288                 my $startrecord=$input->param("ST-$srvid");
289                 ($startrecord) || ($startrecord='0');
290                 my $serverplaceholder='';
291                 foreach ($input->param) {
292                     (next) unless (/ST-(.+)/);
293                     my $serverid=$1;
294                     (next) if ($serverid eq $srvid);
295                     my $place=$input->param("ST-$serverid");
296                     $serverplaceholder.="\&ST-$serverid=$place";
297                 }
298                 if ($numrecords) {
299                     $template->param(HAS_NUMRECORDS => 1);
300                     my $previous='';
301                     my $next='';
302                     if ($startrecord>0) {
303                         $previous="<a href=".$ENV{'SCRIPT_NAME'}."?file=Z-$id&menu=z3950$serverplaceholder\&ST-$srvid=".($startrecord-10)."#SERVER-$srvid>Previous</a>";
304                     }
305                     my $highest;
306                     $highest=$startrecord+10;
307                     ($highest>$numrecords) && ($highest=$numrecords);
308                     if ($numrecords>$startrecord+10) {
309                         $next="<a href=".$ENV{'SCRIPT_NAME'}."?file=Z-$id&menu=z3950$serverplaceholder\&ST-$srvid=$highest#SERVER-$srvid>Next</a>";
310                     }
311                     $template->param(startrecord => $startrecord+1);
312                     $template->param(highest => $highest);
313                     $template->param(numrecords => $numrecords);
314                     $template->param(previous => $previous);
315                     $template->param(next => $next);
316                     my $stj=$dbh->prepare("update z3950results
317                         set highestseen=? where id=?");
318                     $stj->execute($startrecord+10,$resultsid);
319                 }
320
321                 if (! $server ) {
322                     $template->param(PENDING => 1);
323                 } elsif ($enddate == 0) {
324                     my $now=time();
325                     my $elapsed=$now-$startdate;
326                     my $elapsedtime='';
327                     if ($elapsed>60) {
328                         $elapsedtime=sprintf "%d minutes",($elapsed/60);
329                     } else {
330                         $elapsedtime=sprintf "%d seconds",$elapsed;
331                     }
332                     $template->param(elapsedtime => $elapsedtime);
333                 } elsif ($numrecords) {
334                     my @loop = ();
335                     my $z3950file=MARC::File::USMARC->indata ($data);
336                     while (my $record=$z3950file->next) {
337                         my $oldkoha = MARCmarc2koha($dbh,$record);
338                         my %row = ResultRecordLink($dbh,$oldkoha,$resultsid);
339                         push(@loop,\%row);
340                     }
341                     $template->param(LINES => \@loop);
342                 } else {
343                 }
344 #               print "</ul>\n";
345             } # foreach server
346             my $elapsed=time()-$starttimer;
347 #           print "<hr>It took $elapsed seconds to process this page.\n";
348             } else {
349                 $template->param(NO_RECORDS =>1);
350                 $template->param(id => $id);
351             } # if rows
352
353         } else {
354 #
355 # This is an uploaded Marc record
356 #
357             my @loop = ();
358             my $MARCfile = MARC::File::USMARC->indata($data);
359             my $num = 0;
360             while (my $record=$MARCfile->next) {
361                 $num++;
362                 my $oldkoha = MARCmarc2koha($dbh,$record);
363                 my %row = ResultRecordLink($dbh,$oldkoha,'',$num);
364                 push(@loop,\%row);
365             }
366             $template->param(LINES => \@loop);
367         } # if z3950 or marc upload
368         print "Content-Type: text/html\n\n", $template->output;
369 } # sub ListFileRecords
370
371 #--------------
372
373 sub ResultRecordLink {
374     use strict;
375     my ($dbh,$oldkoha,$resultsid, $num)=@_;     # input
376                 # FIXME - $dbh as argument is no longer used
377     my (
378         $sth,
379         $bib,   # hash ref to named fields
380         $searchfield, $searchvalue,
381         $donetext,
382         $fieldname,
383         );
384     my %row = ();
385
386     $dbh = C4::Context->dbh;
387
388 #    $bib=extractmarcfields($record);
389
390     $sth=$dbh->prepare("select *
391           from biblioitems
392           where (isbn=? and isbn!='')  or (issn=? and issn!='')  or (lccn=? and lccn!='') ");
393     $sth->execute($oldkoha->{isbn},$oldkoha->{issn},$oldkoha->{lccn});
394     if ($sth->rows) {
395         $donetext="DONE";
396     } else {
397         $donetext="";
398     }
399     ($oldkoha->{author}) && ($oldkoha->{author}="by $oldkoha->{author}");
400
401     $searchfield="";
402     foreach $fieldname ( "controlnumber", "lccn", "issn", "isbn") {
403         if ( defined $oldkoha->{$fieldname} && $oldkoha->{$fieldname} ) {
404             $searchfield=$fieldname;
405             $searchvalue=$oldkoha->{$fieldname};
406         } # if defined fieldname
407     } # foreach
408     if ( $searchfield ) {
409         $row{SCRIPT_NAME} = $ENV{'SCRIPT_NAME'};
410         $row{donetext}    = $donetext;
411         $row{file}        = $file;
412 #       $row{resultsid}   = $resultsid;
413 #       $row{searchfield} = $searchfield;
414 #       $row{searchvalue} = $searchvalue;
415         $row{numrecord}   = $num;
416         $row{title}       = $oldkoha->{title};
417         $row{author}      = $oldkoha->{author};
418     } else {
419         $row{title} = "Error: Problem with <br>$bib->{title} $bib->{author}<br>";
420     } # if searchfield
421     return %row;
422 } # sub PrintResultRecordLink
423
424 #---------------------------------
425
426 sub z3950menu {
427     use strict;
428     my (
429         $dbh,                   # FIXME - Unused argument
430         $input,
431     )=@_;
432
433     my (
434         $sth, $sti,
435         $processing,
436         $realenddate,
437         $totalrecords,
438         $elapsed,
439         $elapsedtime,
440         $resultstatus, $statuscolor,
441         $id, $term, $type, $done,
442         $startdate, $enddate, $servers,
443         $record,$bib,$title,
444     );
445
446     $dbh = C4::Context->dbh;
447
448     # FIXME - This print statement doesn't belong here. It's just here
449     # so the script will display SOMEthing. But this section really
450     # ought to be properly templated.
451     print <<EOT;
452 Content-Type: text/html;
453
454 <HTML>
455 <BODY>
456 EOT
457
458     print "<a href=$ENV{'SCRIPT_NAME'}>Main Menu</a><hr>\n";
459     print "<table border=0><tr><td valign=top>\n";
460     print "<h2>Results of Z39.50 searches</h2>\n";
461     print "<a href=$ENV{'SCRIPT_NAME'}?menu=z3950>Refresh</a><br>\n" .
462           "<ul>\n";
463
464     # Check queued queries
465     $sth=$dbh->prepare("select id,term,type,done,
466                 startdate,enddate,servers
467         from z3950queue
468         order by id desc
469         limit 20 ");
470     $sth->execute;
471     while ( ($id, $term, $type, $done,
472                 $startdate, $enddate, $servers) = $sth->fetchrow) {
473         $type=uc($type);
474         $term=~s/</&lt;/g;
475         $term=~s/>/&gt;/g;
476
477         $title="";
478         # See if query produced results
479         $sti=$dbh->prepare("select id,server,startdate,enddate,numrecords,results
480                 from z3950results
481                 where queryid=?");
482         $sti->execute($id);
483         if ($sti->rows) {
484             $processing=0;
485             $realenddate=0;
486             $totalrecords=0;
487             while (my ($r_id,$r_server,$r_startdate,$r_enddate,$r_numrecords,$r_marcdata)
488                 = $sti->fetchrow) {
489                 if ($r_enddate==0) {
490                     # It hasn't finished yet
491                     $processing=1;
492                 } else {
493                     # It finished, see how long it took.
494                     if ($r_enddate>$realenddate) {
495                         $realenddate=$r_enddate;
496                     }
497                     # Snag any title from the results if there were any
498                     if ( ! $title && $r_marcdata ) {
499                         ($record)=parsemarcfileformat($r_marcdata);
500                         $bib=extractmarcfields($record);
501                         if ( $bib->{title} ) { $title=$bib->{title} };
502                     } # if no title yet
503                 } # if finished
504
505                 $totalrecords+=$r_numrecords;
506             } # while results
507
508             if ($processing) {
509                 $elapsed=time()-$startdate;
510                 $resultstatus="Processing...";
511                 $statuscolor="red";
512             } else {
513                 $elapsed=$realenddate-$startdate;
514                 $resultstatus="Done.";
515                 $statuscolor="black";
516                 }
517
518                 if ($elapsed>60) {
519                     $elapsedtime=sprintf "%d minutes",($elapsed/60);
520                 } else {
521                     $elapsedtime=sprintf "%d seconds",$elapsed;
522                 }
523                 if ($totalrecords) {
524                     $totalrecords="$totalrecords found.";
525                 } else {
526                     $totalrecords='';
527                 }
528                 print "<li><a href=$ENV{'SCRIPT_NAME'}?file=Z-$id&menu=$menu>".
529                 "$type=$term</a>" .
530                 "<font size=-1 color=$statuscolor>$resultstatus $totalrecords " .
531                 "($elapsedtime) $title </font><br>\n";
532         } else {
533             print "<li><a href=$ENV{'SCRIPT_NAME'}?file=Z-$id&menu=$menu>
534                 $type=$term</a> <font size=-1>Pending</font><br>\n";
535         } # if results done
536     } # while queries
537     print "</ul> </td>\n";
538     # End of query listing
539
540     #------------------------------
541     # Search input form
542     print "<td valign=top width=30%>\n";
543
544     my $sth=$dbh->prepare("select id,name,checked
545         from z3950servers
546         order by rank");
547                 # FIXME - There's already a $sth in this function.
548     $sth->execute;
549     my $serverlist='';
550     while (my ($id, $name, $checked) = $sth->fetchrow) {
551         ($checked) ? ($checked='checked') : ($checked='');
552         $serverlist.="<input type=checkbox name=S-$id $checked> $name<br>\n";
553     }
554     $serverlist.="<input type=checkbox name=S-MAN> <input name=manualz3950server size=25 value=otherserver:210/DATABASE>\n";
555
556     my $rand=rand(1000000000);
557 print << "EOF";
558     <form action=$ENV{'SCRIPT_NAME'} method=GET>
559     <input type=hidden name=z3950queue value=1>
560     <input type=hidden name=menu value=$menu>
561     <p>
562     <input type=hidden name=test value=testvalue>
563     <input type=hidden name=rand value=$rand>
564         <table border=1 bgcolor=#dddddd>
565             <tr><th bgcolor=#bbbbbb colspan=2>Search for MARC records</th></tr>
566     <tr><td>Query Term</td><td><input name=query></td></tr>
567     <tr><td colspan=2 align=center>
568                 <input type=radio name=type value=isbn checked>&nbsp;ISBN
569                 <input type=radio name=type value=lccn        >&nbsp;LCCN<br>
570                 <input type=radio name=type value=author      >&nbsp;Author
571                 <input type=radio name=type value=title       >&nbsp;Title
572                 <input type=radio name=type value=keyword     >&nbsp;Keyword</td></tr>
573             <tr><td colspan=2> $serverlist </td></tr>
574             <tr><td colspan=2 align=center> <input type=submit> </td></tr>
575     </table>
576
577     </form>
578 EOF
579     print "</td></tr></table>\n";
580 } # sub z3950menu
581 #---------------------------------
582
583 sub uploadmarc {
584     use strict;
585     my ($dbh)=@_;               # FIXME - Unused argument
586
587     $dbh = C4::Context->dbh;
588
589     my $template=gettemplate('marcimport/uploadmarc.tmpl');
590     $template->param(SCRIPT_NAME => $ENV{'SCRIPT_NAME'});
591 #    print "<a href=$ENV{'SCRIPT_NAME'}>Main Menu</a><hr>\n";
592     my $sth=$dbh->prepare("select id,name from uploadedmarc");
593     $sth->execute;
594 #    print "<h2>Select a set of MARC records</h2>\n<ul>";
595     my @marc_loop = ();
596     while (my ($id, $name) = $sth->fetchrow) {
597         my %row;
598         $row{id} = $id;
599         $row{name} = $name;
600         push(@marc_loop, \%row);
601 #       print "<li><a href=$ENV{'SCRIPT_NAME'}?file=$id&menu=$menu>$name</a><br>\n";
602     }
603     $template->param(marc => \@marc_loop);
604     print "Content-Type: text/html\n\n", $template->output;
605
606 }
607
608 sub manual {
609 }
610
611
612 sub mainmenu {
613         my $template=gettemplate('marcimport/mainmenu.tmpl');
614         $template->param(SCRIPT_NAME => $ENV{'SCRIPT_NAME'});
615         print "Content-Type: text/html\n\n", $template->output;
616 } # sub mainmenu
617
618 #----------------------------
619 # Accept form results to add query to z3950 queue
620 sub AcceptZ3950Queue {
621     use strict;
622
623     # input parameters
624     my (
625         $dbh,           # DBI handle
626                         # FIXME - Unused argument
627         $input,         # CGI parms
628     )=@_;
629
630     my @serverlist;
631     my $error;
632
633     $dbh = C4::Context->dbh;
634
635     my $query=$input->param('query');
636
637     my $isbngood=1;
638     if ($input->param('type') eq 'isbn') {
639         $isbngood=checkvalidisbn($query);
640     }
641     if ($isbngood) {
642     foreach ($input->param) {
643         if (/S-(.*)/) {
644             my $server=$1;
645             if ($server eq 'MAN') {
646                 push @serverlist, "MAN/".$input->param('manualz3950server')."//"
647 ;
648             } else {
649                 push @serverlist, $server;
650             }
651           }
652         }
653
654         $error=addz3950queue($dbh,$input->param('query'), $input->param('type'),
655                 $input->param('rand'), @serverlist);
656         if ( $error ) {
657             print qq|
658 <table border=1 cellpadding=5 cellspacing=0 align=center>
659 <tr><td bgcolor=#99cc33 background=/images/background-acq.gif colspan=2><font color=red><b>Error</b></font></td></tr>
660 <tr><td colspan=2>
661 <b>$error</b><p>
662 |;
663             if ( $error =~ /daemon/i ) {
664                 print qq|
665 There is a launcher for the Z39.50 client daemon in your intranet installation<br>
666 directory under <b>./scripts/z3950daemon/z3950-daemon-launch.sh</b>.  This<br>
667 script should be run as root, and it will start up the program running with the<br>
668 privileges of your apache user.  Ideally, this script should be started from a<br>
669 system init directory so that is running after the machine starts up.
670 |;
671
672             } # if daemon
673             print qq|
674 </td></tr>
675 </table>
676
677 <table border
678
679 |;
680         } # if error
681     } else {
682         print "<font color=red size=+1>$query is not a valid ISBN
683         Number</font><p>\n";
684     }
685 } # sub AcceptZ3950Queue
686
687 #---------------------------------------------
688 sub AcceptMarcUpload {
689     use strict;
690     my (
691         $dbh,           # DBI handle
692                         # FIXME - Unused argument
693         $input,         # CGI parms
694     )=@_;
695
696     $dbh = C4::Context->dbh;
697
698     my $name=$input->param('name');
699     my $data=$input->param('uploadmarc');
700     my $marcrecord='';
701
702     ($name) || ($name=$data);
703     if (length($data)>0) {
704         while (<$data>) {
705             $marcrecord.=$_;
706         }
707     }
708     my $q_marcrecord=$dbh->quote($marcrecord);
709     my $q_name=$dbh->quote($name);
710     my $sth=$dbh->prepare("insert into uploadedmarc
711                 (marc,name)
712         values ($q_marcrecord, $q_name)");
713     $sth->execute;
714 } # sub AcceptMarcUpload
715
716 #-------------------------------------------
717 sub AcceptBiblioitem {
718     use strict;
719     my (
720         $dbh,                   # FIXME - Unused argument
721         $input,
722     )=@_;
723
724     my $biblionumber=0;
725     my $biblioitemnumber=0;
726     my $sth;
727     my $record;
728
729     $dbh = C4::Context->dbh;
730
731 #    my $isbn=$input->param('isbn');
732 #    my $issn=$input->param('issn');
733 #    my $lccn=$input->param('lccn');
734 #    my $q_origisbn=$dbh->quote($input->param('origisbn'));
735 #    my $q_origissn=$dbh->quote($input->param('origissn'));
736 #    my $q_origlccn=$dbh->quote($input->param('origlccn'));
737 #    my $q_origcontrolnumber=$dbh->quote($input->param('origcontrolnumber'));
738     my $title=$input->param('title');
739
740 #    my $q_isbn=$dbh->quote((($isbn) || ('NIL')));
741 #    my $q_issn=$dbh->quote((($issn) || ('NIL')));
742 #    my $q_lccn=$dbh->quote((($lccn) || ('NIL')));
743     my $file= MARC::File::USMARC->indata($input->param('file'));
744     my $numrecord = $input->param('numrecord');
745     if ($numrecord) {
746         for (my $i=1;$i<$numrecord;$i++) {
747             $record=$file->next;
748         }
749     } else {
750         print STDERR "Error in marcimport.pl/Acceptbiblioitem : numrecord not defined\n";
751         print "Error in marcimport.pl/Acceptbiblioitem : numrecord not defined : contact administrator\n";
752     }
753     my $template=gettemplate('marcimport/AcceptBiblioitem.tmpl');
754
755     my $oldkoha = MARCmarc2koha($dbh,$record);
756     # See if it already exists
757     # FIXME - There's already a $sth in this context.
758     my $sth=$dbh->prepare("select biblionumber,biblioitemnumber
759         from biblioitems
760         where isbn=? or issn=? or lccn=?");
761     $sth->execute($oldkoha->{isbn},$oldkoha->{issn},$oldkoha->{lccn});
762     if ($sth->rows) {
763         # Already exists
764
765         ($biblionumber, $biblioitemnumber) = $sth->fetchrow;
766         $template->param(title => $title);
767         $template->param(biblionumber => $biblionumber);
768         $template->param(biblioitemnumber => $biblioitemnumber);
769         $template->param(BIBLIO_EXISTS => 1);
770
771     } else {
772         # It doesn't exist; add it.
773
774         my $error;
775         my %biblio;
776         my %biblioitem;
777
778         # convert to upper case and split on lines
779         my $subjectheadings=$input->param('subject');
780         my @subjectheadings=split(/[\r\n]+/,$subjectheadings);
781
782         my $additionalauthors=$input->param('additionalauthors');
783         my @additionalauthors=split(/[\r\n]+|\|/,uc($additionalauthors));
784
785         # Use individual assignments to hash buckets, in case
786         #  any of the input parameters are empty or don't exist
787         $biblio{title}          =$input->param('title');
788         $biblio{author}         =$input->param('author');
789         $biblio{copyright}      =$input->param('copyrightdate');
790         $biblio{seriestitle}    =$input->param('seriestitle');
791         $biblio{notes}          =$input->param('notes');
792         $biblio{abstract}       =$input->param('abstract');
793         $biblio{subtitle}       =$input->param('subtitle');
794
795         $biblioitem{volume}             =$input->param('volume');
796         $biblioitem{number}             =$input->param('number');
797         $biblioitem{itemtype}           =$input->param('itemtype');
798         $biblioitem{isbn}               =$input->param('isbn');
799         $biblioitem{issn}               =$input->param('issn');
800         $biblioitem{dewey}              =$input->param('dewey');
801         $biblioitem{subclass}           =$input->param('subclass');
802         $biblioitem{publicationyear}    =$input->param('publicationyear');
803         $biblioitem{publishercode}      =$input->param('publishercode');
804         $biblioitem{volumedate}         =$input->param('volumedate');
805         $biblioitem{volumeddesc}        =$input->param('volumeddesc');
806         $biblioitem{illus}              =$input->param('illustrator');
807         $biblioitem{pages}              =$input->param('pages');
808         $biblioitem{notes}              =$input->param('notes');
809         $biblioitem{size}               =$input->param('size');
810         $biblioitem{place}              =$input->param('place');
811         $biblioitem{lccn}               =$input->param('lccn');
812         $biblioitem{marc}               =$input->param('marc');
813 #       print STDERR $record->as_formatted();
814 #       die;
815         ($biblionumber, $biblioitemnumber, $error)=
816             ALLnewbiblio($dbh,$record,\%biblio,\%biblioitem);
817 #           (1,2,0);
818 #         newcompletebiblioitem($dbh,
819 #               \%biblio,
820 #               \%biblioitem,
821 #               \@subjectheadings,
822 #               \@additionalauthors
823 #       );
824
825         if ( $error ) {
826             print "<H2>Error adding biblio item</H2> $error\n";
827         } else {
828             $template->param(title => $title);
829             $template->param(biblionumber => $biblionumber);
830             $template->param(biblioitemnumber => $biblioitemnumber);
831             $template->param(BIBLIO_CREATE => 1);
832         } # if error
833     } # if new record
834     my $barcode;
835
836     # Get next barcode, or pick random one if none exist yet
837     $sth=$dbh->prepare("select max(barcode) from items");
838     $sth->execute;
839     ($barcode) = $sth->fetchrow;
840     $barcode++;
841     if ($barcode==1) {
842         $barcode=int(rand()*1000000);
843     }
844     my $branchselect=getkeytableselectoptions(
845                 $dbh, 'branches', 'branchcode', 'branchname', 0);
846     $template->param(barcode => $barcode);
847     $template->param(branchselect => $branchselect);
848     print "Content-Type: text/html\n\n", $template->output;
849
850 } # sub ItemCopyForm
851
852 #---------------------------------------
853 # Accept form data to add an item copy
854 sub AcceptItemCopy {
855     use strict;
856     my ( $dbh, $input )=@_;
857                         # FIXME - $dbh argument unused
858
859     my $template=gettemplate('marcimport/AcceptItemCopy.tmpl');
860
861     my $error;
862
863     $dbh = C4::Context->dbh;
864
865     my $barcode=$input->param('barcode');
866     my $replacementprice=($input->param('replacementprice') || 0);
867
868     my $sth=$dbh->prepare("select barcode
869         from items
870         where barcode=?");
871     $sth->execute($barcode);
872     if ($sth->rows) {
873         $template->param(BARCODE_EXISTS => 1);
874         $template->param(barcode => $barcode);
875     } else {
876            # Insert new item into database
877            $error=&ALLnewitem($dbh,
878                                { biblionumber=> $input->param('biblionumber'),
879                                  biblioitemnumber=> $input->param('biblioitemnumber'),
880                                  itemnotes=> $input->param('notes'),
881                                  homebranch=> $input->param('homebranch'),
882                                  replacementprice=> $replacementprice,
883                                  barcode => $barcode
884                                  }
885                                );
886             if ( $error ) {
887                 $template->param(ITEM_ERROR => 1);
888                 $template->param(error => $error);
889             } else {
890                 $template->param(ITEM_CREATED => 1);
891                 $template->param(barcode => $barcode);
892             } # if error
893     } # if barcode exists
894     print "Content-Type: text/html\n\n", $template->output;
895 } # sub AcceptItemCopy
896
897 #---------------------------------------
898 sub FormatMarcText {
899     use strict;
900
901     # Input
902     my (
903         $fields,        # list ref to MARC fields
904     )=@_;
905     # Return
906     my $marctext;
907
908     my (
909         $color,
910         $field,
911         $tag,
912         $label,
913         $indicator,
914         $subfieldcode,$subfieldvalue,
915         @values, $value
916     );
917     my $debug=0;
918
919     #-----------------------------------------
920
921     $marctext="<table border=0 cellspacing=1>
922         <tr><th colspan=4 background=/images/background-acq.gif>
923                 MARC RECORD
924         </th></tr>\n";
925
926     foreach $field ( @$fields ) {
927
928         # Swap colors on alternating lines
929         ($color eq $lc1) ? ($color=$lc2) : ($color=$lc1);
930
931         $tag=$field->{'tag'};
932         $label=taglabel($tag);
933
934         if ( $tag eq 'LDR' ) {
935                 $tag='';
936                 $label="Leader:";
937         }
938         print "<pre>Format tag=$tag label=$label</pre>\n" if $debug;
939
940         $marctext.="<tr><td bgcolor=$color valign=top>$label</td> \n" .
941                 "<td bgcolor=$color valign=top>$tag</td> \n";
942
943         $indicator=$field->{'indicator'};
944         $indicator=~s/ +$//;    # drop trailing blanks
945
946         # Third table column has indicator if it is short.
947         # Fourth column has embedded table of subfields, and indicator
948         #  if it is long (leader or fixed-position fields)
949
950         print "<pre>Format indicator=$indicator" .
951                 " length=" . length( $indicator ) .  "</pre>\n" if $debug;
952         if ( length( $indicator <= 3 ) ) {
953             $marctext.="<td bgcolor=$color valign=top><pre>" .
954                 "$indicator</pre></td>" .
955                 "<td bgcolor=$color valign=top>" ;
956         } else {
957             $marctext.="<td bgcolor=$color valign=top></td>" .
958                 "<td bgcolor=$color valign=top>" .
959                 "$indicator ";
960         } # if length
961
962         # Subfields
963         if ( $field->{'subfields'} )  {
964             # start another table for subfields
965             $marctext.= "<table border=0 cellspacing=2>\n";
966             foreach $subfieldcode ( sort( keys %{ $field->{'subfields'} }   )) {
967                 $subfieldvalue=$field->{'subfields'}->{$subfieldcode};
968                 if (ref($subfieldvalue) eq 'ARRAY' ) {
969                     # if it's a pointer to array, get all the values
970                     @values=@{$subfieldvalue};
971                 } else {
972                     # otherwise get the one value
973                     @values=( $subfieldvalue );
974                 } # if subfield array
975                 foreach $value ( @values ) {
976                   $marctext.="<tr><td><strong>$subfieldcode</strong></td>" .
977                     "<td>$value</td></tr>\n";
978                 } # foreach value
979             } # foreach subfield
980             $marctext.="</table>\n";
981         } # if subfields
982         # End of indicator and subfields column
983         $marctext.="</td>\n";
984
985         # End of columns
986         $marctext.="</tr>\n";
987
988     } # foreach field
989
990     $marctext.="</table>\n";
991
992     return $marctext;
993
994 } # sub FormatMarcText
995
996
997 #---------------
998 # $Log$
999 # Revision 1.1  2002/11/22 10:15:22  tipaul
1000 # moving z3950 related scripts to specific dir
1001 #
1002 # Revision 1.18  2002/10/14 07:41:04  tipaul
1003 # merging arens + my modifs/bugfixes
1004 #
1005 # Revision 1.17  2002/10/13 07:39:26  arensb
1006 # Added magic RCS comment.
1007 # Removed trailing whitespace.
1008 #
1009 # Revision 1.16  2002/10/11 12:45:10  arensb
1010 # Replaced &requireDBI with C4::Context->dbh, thus making the "use
1011 # Fixed muffed quotes in &gettemplate calls.
1012 # Added a temporary print statement in &z3950menu, so it'll print
1013 # something instead of giving a browser error.
1014 #
1015 # Revision 1.15  2002/10/09 18:09:16  tonnesen
1016 # switched from picktemplate() to gettemplate()
1017 #
1018 # Revision 1.14  2002/10/05 09:56:14  arensb
1019 # Merged with arensb-context branch: use C4::Context->dbh instead of
1020 # &C4Connect, and generally prefer C4::Context over C4::Database.
1021 #
1022 # Revision 1.13.2.1  2002/10/04 02:52:50  arensb
1023 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
1024 # C4Connect.
1025 # Removed old code for reading /etc/koha.conf.
1026 #
1027 # Revision 1.13  2002/08/14 18:12:52  tonnesen
1028 # Added copyright statement to all .pl and .pm files
1029 #
1030 # Revision 1.12  2002/07/24 16:24:20  tipaul
1031 # Now, the acqui.simple system...
1032 # marcimport.pl has been almost completly rewritten, so LOT OF BUGS TO COME !!! You've been warned. It seems to work, but...
1033 #
1034 # As with my former messages, nothing seems to have been changed... but ...
1035 # * marcimport now uses HTML::Template.
1036 # * marcimport now uses MARC::Record. that means that when you import a record, the old-DB is populated with the data as in version 1.2, but the MARC-DB part is filled with full MARC::Record.
1037 #
1038 # <IMPORTANT NOTE>
1039 # to get correct response times, you MUST add an index on isbn, issn and lccn rows in biblioitem table. Note this should be done in 1.2 too...
1040 # </IMPORTANT NOTE>
1041 #
1042 # <IMPORTANT NOTE2>
1043 # acqui.simple manage biblio, biblioitems and items tables quite properly. Normal acquisition system manages biblio, biblioitems BUT NOT items. That will be done in the near future...
1044 # </IMPORTANT NOTE2>
1045 #
1046 # what's next now ?
1047 # * bug tracking, of course... Surely a dozen of dozens...
1048 # * LOT of developpments, i'll surely write a mail to koha-devel tomorrow (as it's time for dinner in France, and i plan to play NeverwinterNights after dinner ;-) ...
1049 #
1050 # Revision 1.6.2.32  2002/06/29 17:33:47  amillar
1051 # Allow DEFAULT as input to addz3950search.
1052 # Check for existence of pid file (cat crashed otherwise).
1053 # Return error messages in addz3950search.
1054 #
1055 # Revision 1.6.2.31  2002/06/28 18:50:46  tonnesen
1056 # Got rid of white text on black, replaced with black on background-acq.gif
1057 #
1058 # Revision 1.6.2.30  2002/06/28 18:07:27  tonnesen
1059 # marcimport.pl will print an error message if it can not signal the
1060 # processz3950queue program.  The message contains instructions for starting the
1061 # daemon.
1062 #
1063 # Revision 1.6.2.29  2002/06/27 18:35:01  tonnesen
1064 # $deweyinput was always defined (it's an HTML input field).  Check against
1065 # $bib->{dewey} instead.
1066 #
1067 # Revision 1.6.2.28  2002/06/27 17:41:26  tonnesen
1068 # Applying patch from Matt Kraai to pick F or NF based on presense of a dewey
1069 # number when adding a book via marcimport.pl
1070 #
1071 # Revision 1.6.2.27  2002/06/26 15:52:55  amillar
1072 # Fix display of marc tag labels and indicators
1073 #
1074 # Revision 1.6.2.26  2002/06/26 14:28:35  amillar
1075 # Removed subroutines now existing in modules: extractmarcfields,
1076 #  parsemarcfileformat, addz3950queue, getkeytableselectoptions
1077 #