removing NEW text, it was for testing purposes.
[koha.git] / C4 / Biblio.pm
1 package C4::Biblio;
2
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19
20 use strict;
21 require Exporter;
22 use C4::Context;
23 use C4::Database;
24 use MARC::Record;
25
26 use vars qw($VERSION @ISA @EXPORT);
27
28 # set the version for version checking
29 $VERSION = 0.01;
30
31 @ISA = qw(Exporter);
32
33 #
34 # don't forget MARCxxx subs are exported only for testing purposes. Should not be used
35 # as the old-style API and the NEW one are the only public functions.
36 #
37 @EXPORT = qw(
38   &updateBiblio &updateBiblioItem &updateItem
39   &itemcount &newbiblio &newbiblioitem
40   &modnote &newsubject &newsubtitle
41   &modbiblio &checkitems
42   &newitems &modbibitem
43   &modsubtitle &modsubject &modaddauthor &moditem &countitems
44   &delitem &deletebiblioitem &delbiblio
45   &getbiblio
46   &getbiblioitembybiblionumber
47   &getbiblioitem &getitemsbybiblioitem
48   &skip &getitemtypes
49   &newcompletebiblioitem
50
51   &MARCfind_oldbiblionumber_from_MARCbibid
52   &MARCfind_MARCbibid_from_oldbiblionumber
53   &MARCfind_marc_from_kohafield
54   &MARCfindsubfield
55   &MARCfind_frameworkcode
56   &MARCgettagslib
57
58   &NEWnewbiblio &NEWnewitem
59   &NEWmodbiblio &NEWmoditem
60   &NEWdelbiblio &NEWdelitem
61   &NEWmodbiblioframework
62
63   &MARCaddbiblio &MARCadditem
64   &MARCmodsubfield &MARCaddsubfield
65   &MARCmodbiblio &MARCmoditem
66   &MARCkoha2marcBiblio &MARCmarc2koha
67   &MARCkoha2marcItem &MARChtml2marc
68   &MARCgetbiblio &MARCgetitem
69   &MARCaddword &MARCdelword
70   &MARCdelsubfield
71   &char_decode
72   
73   &FindDuplicate
74   &DisplayISBN
75 );
76
77 #
78 #
79 # MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC MARC
80 #
81 #
82 # all the following subs takes a MARC::Record as parameter and manage
83 # the MARC-DB. They are called by the 1.0/1.2 xxx subs, and by the
84 # NEWxxx subs (xxx deals with old-DB parameters, the NEWxxx deals with MARC-DB parameter)
85
86 =head1 NAME
87
88 C4::Biblio - acquisition, catalog  management functions
89
90 =head1 SYNOPSIS
91
92 move from 1.2 to 1.4 version :
93 1.2 and previous version uses a specific API to manage biblios. This API uses old-DB style parameters.
94 In the 1.4 version, we want to do 2 differents things :
95  - keep populating the old-DB, that has a LOT less datas than MARC
96  - populate the MARC-DB
97 To populate the DBs we have 2 differents sources :
98  - the standard acquisition system (through book sellers), that does'nt use MARC data
99  - the MARC acquisition system, that uses MARC data.
100
101 Thus, we have 2 differents cases :
102 - with the standard acquisition system, we have non MARC data and want to populate old-DB and MARC-DB, knowing it's an incomplete MARC-record
103 - with the MARC acquisition system, we have MARC datas, and want to loose nothing in MARC-DB. So, we can't store datas in old-DB, then copy in MARC-DB. we MUST have an API for true MARC data, that populate MARC-DB then old-DB
104
105 That's why we need 4 subs :
106 all I<subs beginning by MARC> manage only MARC tables. They manage MARC-DB with MARC::Record parameters
107 all I<subs beginning by OLD> manage only OLD-DB tables. They manage old-DB with old-DB parameters
108 all I<subs beginning by NEW> manage both OLD-DB and MARC tables. They use MARC::Record as parameters. it's the API that MUST be used in MARC acquisition system
109 all I<subs beginning by seomething else> are the old-style API. They use old-DB as parameter, then call internally the OLD and MARC subs.
110
111 - NEW and old-style API should be used in koha to manage biblio
112 - MARCsubs are divided in 2 parts :
113 * some of them manage MARC parameters. They are heavily used in koha.
114 * some of them manage MARC biblio : they are mostly used by NEW and old-style subs.
115 - OLD are used internally only
116
117 all subs requires/use $dbh as 1st parameter.
118
119 I<NEWxxx related subs>
120
121 all subs requires/use $dbh as 1st parameter.
122 those subs are used by the MARC-compliant version of koha : marc import, or marc management.
123
124 I<OLDxxx related subs>
125
126 all subs requires/use $dbh as 1st parameter.
127 those subs are used by the MARC-compliant version of koha : marc import, or marc management.
128
129 They all are the exact copy of 1.0/1.2 version of the sub without the OLD.
130 The OLDxxx is called by the original xxx sub.
131 the 1.4 xxx sub also builds MARC::Record an calls the MARCxxx
132
133 WARNING : there is 1 difference between initialxxx and OLDxxx :
134 the db header $dbh is always passed as parameter to avoid over-DB connexion
135
136 =head1 DESCRIPTION
137
138 =over 4
139
140 =item @tagslib = &MARCgettagslib($dbh,1|0,$itemtype);
141
142 last param is 1 for liblibrarian and 0 for libopac
143 $itemtype contains the itemtype framework reference. If empty or does not exist, the default one is used
144 returns a hash with tag/subfield meaning
145 =item ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,$kohafield);
146
147 finds MARC tag and subfield for a given kohafield
148 kohafield is "table.field" where table= biblio|biblioitems|items, and field a field of the previous table
149
150 =item $biblionumber = &MARCfind_oldbiblionumber_from_MARCbibid($dbh,$MARCbibi);
151
152 finds a old-db biblio number for a given MARCbibid number
153
154 =item $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$oldbiblionumber);
155
156 finds a MARC bibid from a old-db biblionumber
157
158 =item $MARCRecord = &MARCkoha2marcBiblio($dbh,$biblionumber,biblioitemnumber);
159
160 MARCkoha2marcBiblio is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB biblio/biblioitem
161
162 =item $MARCRecord = &MARCkoha2marcItem($dbh,$biblionumber,itemnumber);
163
164 MARCkoha2marcItem is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB item
165
166 =item $MARCRecord = &MARCkoha2marcSubtitle($dbh,$biblionumber,$subtitle);
167
168 MARCkoha2marcSubtitle is a wrapper between old-DB and MARC-DB. It returns a MARC::Record builded with old-DB subtitle
169
170 =item $olddb = &MARCmarc2koha($dbh,$MARCRecord);
171
172 builds a hash with old-db datas from a MARC::Record
173
174 =item &MARCaddbiblio($dbh,$MARC::Record,$biblionumber);
175
176 creates a biblio (in the MARC tables only). $biblionumber is the old-db biblionumber of the biblio
177
178 =item &MARCaddsubfield($dbh,$bibid,$tagid,$indicator,$tagorder,$subfieldcode,$subfieldorder,$subfieldvalue);
179
180 adds a subfield in a biblio (in the MARC tables only).
181
182 =item $MARCRecord = &MARCgetbiblio($dbh,$bibid);
183
184 Returns a MARC::Record for the biblio $bibid.
185
186 =item &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,$delete);
187
188 MARCmodbiblio changes a biblio for a biblio,MARC::Record passed as parameter
189 It 1st delete the biblio, then recreates it.
190 WARNING : the $delete parameter is not used anymore (too much unsolvable cases).
191 =item ($subfieldid,$subfieldvalue) = &MARCmodsubfield($dbh,$subfieldid,$subfieldvalue);
192
193 MARCmodsubfield changes the value of a given subfield
194
195 =item $subfieldid = &MARCfindsubfield($dbh,$bibid,$tag,$subfieldcode,$subfieldorder,$subfieldvalue);
196
197 MARCfindsubfield returns a subfield number given a bibid/tag/subfieldvalue values.
198 Returns -1 if more than 1 answer
199
200 =item $subfieldid = &MARCfindsubfieldid($dbh,$bibid,$tag,$tagorder,$subfield,$subfieldorder);
201
202 MARCfindsubfieldid find a subfieldid for a bibid/tag/tagorder/subfield/subfieldorder
203
204 =item &MARCdelsubfield($dbh,$bibid,$tag,$tagorder,$subfield,$subfieldorder);
205
206 MARCdelsubfield delete a subfield for a bibid/tag/tagorder/subfield/subfieldorder
207 If $subfieldorder is not set, delete all the $tag$subfield subfields 
208
209 =item &MARCdelbiblio($dbh,$bibid);
210
211 MARCdelbiblio delete biblio $bibid
212
213 =item &MARCkoha2marcOnefield
214
215 used by MARCkoha2marc and should not be useful elsewhere
216
217 =item &MARCmarc2kohaOnefield
218
219 used by MARCmarc2koha and should not be useful elsewhere
220
221 =item MARCaddword
222
223 used to manage MARC_word table and should not be useful elsewhere
224
225 =item MARCdelword
226
227 used to manage MARC_word table and should not be useful elsewhere
228
229 =cut
230
231 sub MARCgettagslib {
232     my ( $dbh, $forlibrarian, $frameworkcode ) = @_;
233     $frameworkcode = "" unless $frameworkcode;
234     my $sth;
235     my $libfield = ( $forlibrarian eq 1 ) ? 'liblibrarian' : 'libopac';
236
237     # check that framework exists
238     $sth =
239       $dbh->prepare(
240         "select count(*) from marc_tag_structure where frameworkcode=?");
241     $sth->execute($frameworkcode);
242     my ($total) = $sth->fetchrow;
243     $frameworkcode = "" unless ( $total > 0 );
244     $sth =
245       $dbh->prepare(
246 "select tagfield,liblibrarian,libopac,mandatory,repeatable from marc_tag_structure where frameworkcode=? order by tagfield"
247     );
248     $sth->execute($frameworkcode);
249     my ( $liblibrarian, $libopac, $tag, $res, $tab, $mandatory, $repeatable );
250
251     while ( ( $tag, $liblibrarian, $libopac, $mandatory, $repeatable ) = $sth->fetchrow ) {
252         $res->{$tag}->{lib}        = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
253         $res->{$tab}->{tab}        = "";            # XXX
254         $res->{$tag}->{mandatory}  = $mandatory;
255         $res->{$tag}->{repeatable} = $repeatable;
256     }
257
258     $sth =
259       $dbh->prepare(
260 "select tagfield,tagsubfield,liblibrarian,libopac,tab, mandatory, repeatable,authorised_value,authtypecode,value_builder,kohafield,seealso,hidden,isurl,link from marc_subfield_structure where frameworkcode=? order by tagfield,tagsubfield"
261     );
262     $sth->execute($frameworkcode);
263
264     my $subfield;
265     my $authorised_value;
266     my $authtypecode;
267     my $value_builder;
268     my $kohafield;
269     my $seealso;
270     my $hidden;
271     my $isurl;
272         my $link;
273
274     while (
275         ( $tag,         $subfield,   $liblibrarian,   , $libopac,      $tab,
276         $mandatory,     $repeatable, $authorised_value, $authtypecode,
277         $value_builder, $kohafield,  $seealso,          $hidden,
278         $isurl,                 $link )
279         = $sth->fetchrow
280       )
281     {
282         $res->{$tag}->{$subfield}->{lib}              = ($forlibrarian or !$libopac)?$liblibrarian:$libopac;
283         $res->{$tag}->{$subfield}->{tab}              = $tab;
284         $res->{$tag}->{$subfield}->{mandatory}        = $mandatory;
285         $res->{$tag}->{$subfield}->{repeatable}       = $repeatable;
286         $res->{$tag}->{$subfield}->{authorised_value} = $authorised_value;
287         $res->{$tag}->{$subfield}->{authtypecode}     = $authtypecode;
288         $res->{$tag}->{$subfield}->{value_builder}    = $value_builder;
289         $res->{$tag}->{$subfield}->{kohafield}        = $kohafield;
290         $res->{$tag}->{$subfield}->{seealso}          = $seealso;
291         $res->{$tag}->{$subfield}->{hidden}           = $hidden;
292         $res->{$tag}->{$subfield}->{isurl}            = $isurl;
293         $res->{$tag}->{$subfield}->{link}            = $link;
294     }
295     return $res;
296 }
297
298 sub MARCfind_marc_from_kohafield {
299     my ( $dbh, $kohafield,$frameworkcode ) = @_;
300     return 0, 0 unless $kohafield;
301         my $relations = C4::Context->marcfromkohafield;
302         return ($relations->{$frameworkcode}->{$kohafield}->[0],$relations->{$frameworkcode}->{$kohafield}->[1]);
303 }
304
305 sub MARCfind_oldbiblionumber_from_MARCbibid {
306     my ( $dbh, $MARCbibid ) = @_;
307     my $sth =
308       $dbh->prepare("select biblionumber from marc_biblio where bibid=?");
309     $sth->execute($MARCbibid);
310     my ($biblionumber) = $sth->fetchrow;
311     return $biblionumber;
312 }
313
314 sub MARCfind_MARCbibid_from_oldbiblionumber {
315     my ( $dbh, $oldbiblionumber ) = @_;
316     my $sth =
317       $dbh->prepare("select bibid from marc_biblio where biblionumber=?");
318     $sth->execute($oldbiblionumber);
319     my ($bibid) = $sth->fetchrow;
320     return $bibid;
321 }
322
323 sub MARCaddbiblio {
324
325 # pass the MARC::Record to this function, and it will create the records in the marc tables
326         my ($dbh,$record,$biblionumber,$frameworkcode,$bibid) = @_;
327         my @fields=$record->fields();
328 # my $bibid;
329 # adding main table, and retrieving bibid
330 # if bibid is sent, then it's not a true add, it's only a re-add, after a delete (ie, a mod)
331     # if bibid empty => true add, find a new bibid number
332     unless ($bibid) {
333         $dbh->do(
334 "lock tables marc_biblio WRITE,marc_subfield_table WRITE, marc_word WRITE, marc_blob_subfield WRITE, stopwords READ"
335         );
336         my $sth =
337           $dbh->prepare(
338 "insert into marc_biblio (datecreated,biblionumber,frameworkcode) values (now(),?,?)"
339         );
340         $sth->execute( $biblionumber, $frameworkcode );
341         $sth = $dbh->prepare("select max(bibid) from marc_biblio");
342         $sth->execute;
343         ($bibid) = $sth->fetchrow;
344         $sth->finish;
345     }
346     my $fieldcount = 0;
347
348     # now, add subfields...
349     foreach my $field (@fields) {
350         $fieldcount++;
351         if ( $field->tag() < 10 ) {
352             &MARCaddsubfield( $dbh, $bibid, $field->tag(), '', $fieldcount, '',
353                 1, $field->data() );
354         }
355         else {
356             my @subfields = $field->subfields();
357             foreach my $subfieldcount ( 0 .. $#subfields ) {
358                 &MARCaddsubfield(
359                     $dbh,
360                     $bibid,
361                     $field->tag(),
362                     $field->indicator(1) . $field->indicator(2),
363                     $fieldcount,
364                     $subfields[$subfieldcount][0],
365                     $subfieldcount + 1,
366                     $subfields[$subfieldcount][1]
367                 );
368             }
369         }
370     }
371         # save leader
372         &MARCaddsubfield($dbh,$bibid,'000','',$fieldcount+1,'',1,$record->leader);
373     $dbh->do("unlock tables");
374     return $bibid;
375 }
376
377 sub MARCadditem {
378
379 # pass the MARC::Record to this function, and it will create the records in the marc tables
380     my ($dbh,$record,$biblionumber) = @_;
381 # search for MARC biblionumber
382     $dbh->do("lock tables marc_biblio WRITE,marc_subfield_table WRITE, marc_word WRITE, marc_blob_subfield WRITE, stopwords READ");
383     my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
384     my @fields=$record->fields();
385     my $sth = $dbh->prepare("select max(tagorder) from marc_subfield_table where bibid=?");
386     $sth->execute($bibid);
387     my ($fieldcount) = $sth->fetchrow;
388
389     # now, add subfields...
390     foreach my $field (@fields) {
391         my @subfields = $field->subfields();
392         $fieldcount++;
393         foreach my $subfieldcount ( 0 .. $#subfields ) {
394             &MARCaddsubfield(
395                 $dbh,
396                 $bibid,
397                 $field->tag(),
398                 $field->indicator(1) . $field->indicator(2),
399                 $fieldcount,
400                 $subfields[$subfieldcount][0],
401                 $subfieldcount + 1,
402                 $subfields[$subfieldcount][1]
403             );
404         }
405     }
406     $dbh->do("unlock tables");
407     return $bibid;
408 }
409
410 sub MARCaddsubfield {
411
412     # Add a new subfield to a tag into the DB.
413     my (
414         $dbh,      $bibid,        $tagid,         $tag_indicator,
415         $tagorder, $subfieldcode, $subfieldorder, $subfieldvalues
416       )
417       = @_;
418           return unless $subfieldvalues;
419 # warn "$tagid / $subfieldcode / $subfieldvalues";
420     # if not value, end of job, we do nothing
421 #     if ( length($subfieldvalues) == 0 ) {
422 #         return;
423 #     }
424     if ( not($subfieldcode) ) {
425         $subfieldcode = ' ';
426     }
427     my @subfieldvalues = split /\||#/, $subfieldvalues;
428     foreach my $subfieldvalue (@subfieldvalues) {
429         if ( length($subfieldvalue) > 255 ) {
430             $dbh->do(
431 "lock tables marc_blob_subfield WRITE, marc_subfield_table WRITE"
432             );
433             my $sth =
434               $dbh->prepare(
435                 "insert into marc_blob_subfield (subfieldvalue) values (?)");
436             $sth->execute($subfieldvalue);
437             $sth =
438               $dbh->prepare("select max(blobidlink)from marc_blob_subfield");
439             $sth->execute;
440             my ($res) = $sth->fetchrow;
441             $sth =
442               $dbh->prepare(
443 "insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,valuebloblink) values (?,?,?,?,?,?,?)"
444             );
445             $sth->execute( $bibid, ( sprintf "%03s", $tagid ), $tagorder,
446                 $tag_indicator, $subfieldcode, $subfieldorder, $res );
447
448             if ( $sth->errstr ) {
449                 warn
450 "ERROR ==> insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values ($bibid,$tagid,$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue)\n";
451             }
452             $dbh->do("unlock tables");
453         }
454         else {
455             my $sth =
456               $dbh->prepare(
457 "insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values (?,?,?,?,?,?,?)"
458             );
459             $sth->execute(
460                 $bibid,        ( sprintf "%03s", $tagid ),
461                 $tagorder,     $tag_indicator,
462                 $subfieldcode, $subfieldorder,
463                 $subfieldvalue
464             );
465             if ( $sth->errstr ) {
466                 warn
467 "ERROR ==> insert into marc_subfield_table (bibid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue) values ($bibid,$tagid,$tagorder,$tag_indicator,$subfieldcode,$subfieldorder,$subfieldvalue)\n";
468             }
469         }
470         &MARCaddword(
471             $dbh,          $bibid,         $tagid,       $tagorder,
472             $subfieldcode, $subfieldorder, $subfieldvalue
473         );
474     }
475 }
476
477 sub MARCgetbiblio {
478
479     # Returns MARC::Record of the biblio passed in parameter.
480     my ( $dbh, $bibid ) = @_;
481     my $record = MARC::Record->new();
482 #       warn "". $bidid;
483
484     my $sth =
485       $dbh->prepare(
486 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
487                                  from marc_subfield_table
488                                  where bibid=? order by tag,tagorder,subfieldorder
489                          "
490     );
491     my $sth2 =
492       $dbh->prepare(
493         "select subfieldvalue from marc_blob_subfield where blobidlink=?");
494     $sth->execute($bibid);
495     my $prevtagorder = 1;
496     my $prevtag      = 'XXX';
497     my $previndicator;
498     my $field;        # for >=10 tags
499     my $prevvalue;    # for <10 tags
500     while ( my $row = $sth->fetchrow_hashref ) {
501
502         if ( $row->{'valuebloblink'} ) {    #---- search blob if there is one
503             $sth2->execute( $row->{'valuebloblink'} );
504             my $row2 = $sth2->fetchrow_hashref;
505             $sth2->finish;
506             $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
507         }
508         if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
509             $previndicator .= "  ";
510             if ( $prevtag < 10 ) {
511                                 if ($prevtag ne '000') {
512                         $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX";    # ignore the 1st loop
513                                 } else {
514                                         $record->leader(sprintf("%24s",$prevvalue));
515                                 }
516             }
517             else {
518                 $record->add_fields($field) unless $prevtag eq "XXX";
519             }
520             undef $field;
521             $prevtagorder  = $row->{tagorder};
522             $prevtag       = $row->{tag};
523             $previndicator = $row->{tag_indicator};
524             if ( $row->{tag} < 10 ) {
525                 $prevvalue = $row->{subfieldvalue};
526             }
527             else {
528                 $field = MARC::Field->new(
529                     ( sprintf "%03s", $prevtag ),
530                     substr( $row->{tag_indicator} . '  ', 0, 1 ),
531                     substr( $row->{tag_indicator} . '  ', 1, 1 ),
532                     $row->{'subfieldcode'},
533                     $row->{'subfieldvalue'}
534                 );
535             }
536         }
537         else {
538             if ( $row->{tag} < 10 ) {
539                 $record->add_fields( ( sprintf "%03s", $row->{tag} ),
540                     $row->{'subfieldvalue'} );
541             }
542             else {
543                 $field->add_subfields( $row->{'subfieldcode'},
544                     $row->{'subfieldvalue'} );
545             }
546             $prevtag       = $row->{tag};
547             $previndicator = $row->{tag_indicator};
548         }
549     }
550
551     # the last has not been included inside the loop... do it now !
552     if ( $prevtag ne "XXX" )
553     { # check that we have found something. Otherwise, prevtag is still XXX and we
554          # must return an empty record, not make MARC::Record fail because we try to
555          # create a record with XXX as field :-(
556         if ( $prevtag < 10 ) {
557             $record->add_fields( $prevtag, $prevvalue );
558         }
559         else {
560
561             #           my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
562             $record->add_fields($field);
563         }
564     }
565     return $record;
566 }
567
568 sub MARCgetitem {
569
570     # Returns MARC::Record of the biblio passed in parameter.
571     my ( $dbh, $bibid, $itemnumber ) = @_;
572     my $record = MARC::Record->new();
573
574     # search MARC tagorder
575     my $sth2 =
576       $dbh->prepare(
577 "select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
578     );
579     $sth2->execute( $bibid, $itemnumber );
580     my ($tagorder) = $sth2->fetchrow_array();
581
582     #---- TODO : the leader is missing
583     my $sth =
584       $dbh->prepare(
585 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
586                                  from marc_subfield_table
587                                  where bibid=? and tagorder=? order by subfieldcode,subfieldorder
588                          "
589     );
590     $sth2 =
591       $dbh->prepare(
592         "select subfieldvalue from marc_blob_subfield where blobidlink=?");
593     $sth->execute( $bibid, $tagorder );
594     while ( my $row = $sth->fetchrow_hashref ) {
595         if ( $row->{'valuebloblink'} ) {    #---- search blob if there is one
596             $sth2->execute( $row->{'valuebloblink'} );
597             my $row2 = $sth2->fetchrow_hashref;
598             $sth2->finish;
599             $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
600         }
601         if ( $record->field( $row->{'tag'} ) ) {
602             my $field;
603
604 #--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
605             #--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
606             if ( length( $row->{'tag'} ) < 3 ) {
607                 $row->{'tag'} = "0" . $row->{'tag'};
608             }
609             $field = $record->field( $row->{'tag'} );
610             if ($field) {
611                 my $x =
612                   $field->add_subfields( $row->{'subfieldcode'},
613                     $row->{'subfieldvalue'} );
614                 $record->delete_field($field);
615                 $record->add_fields($field);
616             }
617         }
618         else {
619             if ( length( $row->{'tag'} ) < 3 ) {
620                 $row->{'tag'} = "0" . $row->{'tag'};
621             }
622             my $temp =
623               MARC::Field->new( $row->{'tag'}, " ", " ",
624                 $row->{'subfieldcode'} => $row->{'subfieldvalue'} );
625             $record->add_fields($temp);
626         }
627
628     }
629     return $record;
630 }
631
632 sub MARCmodbiblio {
633         my ($dbh,$bibid,$record,$frameworkcode,$delete)=@_;
634 # 1st delete the biblio,
635 # 2nd recreate it
636         my $biblionumber = MARCfind_oldbiblionumber_from_MARCbibid($dbh,$bibid);
637         &MARCdelbiblio($dbh,$bibid,1);
638         &MARCaddbiblio($dbh,$record,$biblionumber,$frameworkcode,$bibid);
639 }
640
641 sub MARCdelbiblio {
642     my ( $dbh, $bibid, $keep_items ) = @_;
643
644     # if the keep_item is set to 1, then all items are preserved.
645     # This flag is set when the delbiblio is called by modbiblio
646     # due to a too complex structure of MARC (repeatable fields and subfields),
647     # the best solution for a modif is to delete / recreate the record.
648
649 # 1st of all, copy the MARC::Record to deletedbiblio table => if a true deletion, MARC data will be kept.
650 # if deletion called before MARCmodbiblio => won't do anything, as the oldbiblionumber doesn't
651     # exist in deletedbiblio table
652     my $record = MARCgetbiblio( $dbh, $bibid );
653     my $oldbiblionumber =
654       MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
655     my $copy2deleted =
656       $dbh->prepare("update deletedbiblio set marc=? where biblionumber=?");
657     $copy2deleted->execute( $record->as_usmarc(), $oldbiblionumber );
658
659     # now, delete in MARC tables.
660     if ( $keep_items eq 1 ) {
661
662         #search item field code
663         my $sth =
664           $dbh->prepare(
665 "select tagfield from marc_subfield_structure where kohafield like 'items.%'"
666         );
667         $sth->execute;
668         my $itemtag = $sth->fetchrow_hashref->{tagfield};
669         $dbh->do(
670 "delete from marc_subfield_table where bibid=$bibid and tag<>$itemtag"
671         );
672         $dbh->do(
673 "delete from marc_word where bibid=$bibid and not (tagsubfield like \"$itemtag%\")"
674         );
675     }
676     else {
677         $dbh->do("delete from marc_biblio where bibid=$bibid");
678         $dbh->do("delete from marc_subfield_table where bibid=$bibid");
679         $dbh->do("delete from marc_word where bibid=$bibid");
680     }
681 }
682
683 sub MARCdelitem {
684
685     # delete the item passed in parameter in MARC tables.
686     my ( $dbh, $bibid, $itemnumber ) = @_;
687
688     #    my $record = MARC::Record->new();
689     # search MARC tagorder
690     my $record = MARCgetitem( $dbh, $bibid, $itemnumber );
691     my $copy2deleted =
692       $dbh->prepare("update deleteditems set marc=? where itemnumber=?");
693     $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
694
695     my $sth2 =
696       $dbh->prepare(
697 "select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
698     );
699     $sth2->execute( $bibid, $itemnumber );
700     my ($tagorder) = $sth2->fetchrow_array();
701     my $sth =
702       $dbh->prepare(
703         "delete from marc_subfield_table where bibid=? and tagorder=?");
704     $sth->execute( $bibid, $tagorder );
705 }
706
707 sub MARCmoditem {
708         my ($dbh,$record,$bibid,$itemnumber,$delete)=@_;
709         my $biblionumber = MARCfind_oldbiblionumber_from_MARCbibid($dbh,$bibid);
710         &MARCdelitem($dbh,$bibid,$itemnumber);
711         &MARCadditem($dbh,$record,$biblionumber);
712 }
713
714 sub MARCmodsubfield {
715
716     # Subroutine changes a subfield value given a subfieldid.
717     my ( $dbh, $subfieldid, $subfieldvalue ) = @_;
718     $dbh->do("lock tables marc_blob_subfield WRITE,marc_subfield_table WRITE");
719     my $sth1 =
720       $dbh->prepare(
721         "select valuebloblink from marc_subfield_table where subfieldid=?");
722     $sth1->execute($subfieldid);
723     my ($oldvaluebloblink) = $sth1->fetchrow;
724     $sth1->finish;
725     my $sth;
726
727     # if too long, use a bloblink
728     if ( length($subfieldvalue) > 255 ) {
729
730         # if already a bloblink, update it, otherwise, insert a new one.
731         if ($oldvaluebloblink) {
732             $sth =
733               $dbh->prepare(
734 "update marc_blob_subfield set subfieldvalue=? where blobidlink=?"
735             );
736             $sth->execute( $subfieldvalue, $oldvaluebloblink );
737         }
738         else {
739             $sth =
740               $dbh->prepare(
741                 "insert into marc_blob_subfield (subfieldvalue) values (?)");
742             $sth->execute($subfieldvalue);
743             $sth =
744               $dbh->prepare("select max(blobidlink) from marc_blob_subfield");
745             $sth->execute;
746             my ($res) = $sth->fetchrow;
747             $sth =
748               $dbh->prepare(
749 "update marc_subfield_table set subfieldvalue=null, valuebloblink=? where subfieldid=?"
750             );
751             $sth->execute( $res, $subfieldid );
752         }
753     }
754     else {
755
756 # note this can leave orphan bloblink. Not a big problem, but we should build somewhere a orphan deleting script...
757         $sth =
758           $dbh->prepare(
759 "update marc_subfield_table set subfieldvalue=?,valuebloblink=null where subfieldid=?"
760         );
761         $sth->execute( $subfieldvalue, $subfieldid );
762     }
763     $dbh->do("unlock tables");
764     $sth->finish;
765     $sth =
766       $dbh->prepare(
767 "select bibid,tag,tagorder,subfieldcode,subfieldid,subfieldorder from marc_subfield_table where subfieldid=?"
768     );
769     $sth->execute($subfieldid);
770     my ( $bibid, $tagid, $tagorder, $subfieldcode, $x, $subfieldorder ) =
771       $sth->fetchrow;
772     $subfieldid = $x;
773     &MARCdelword( $dbh, $bibid, $tagid, $tagorder, $subfieldcode,
774         $subfieldorder );
775     &MARCaddword(
776         $dbh,          $bibid,         $tagid,       $tagorder,
777         $subfieldcode, $subfieldorder, $subfieldvalue
778     );
779     return ( $subfieldid, $subfieldvalue );
780 }
781
782 sub MARCfindsubfield {
783     my ( $dbh, $bibid, $tag, $subfieldcode, $subfieldorder, $subfieldvalue ) =
784       @_;
785     my $resultcounter = 0;
786     my $subfieldid;
787     my $lastsubfieldid;
788     my $query =
789 "select subfieldid from marc_subfield_table where bibid=? and tag=? and subfieldcode=?";
790     my @bind_values = ( $bibid, $tag, $subfieldcode );
791     if ($subfieldvalue) {
792         $query .= " and subfieldvalue=?";
793         push ( @bind_values, $subfieldvalue );
794     }
795     else {
796         if ( $subfieldorder < 1 ) {
797             $subfieldorder = 1;
798         }
799         $query .= " and subfieldorder=?";
800         push ( @bind_values, $subfieldorder );
801     }
802     my $sti = $dbh->prepare($query);
803     $sti->execute(@bind_values);
804     while ( ($subfieldid) = $sti->fetchrow ) {
805         $resultcounter++;
806         $lastsubfieldid = $subfieldid;
807     }
808     if ( $resultcounter > 1 ) {
809
810 # Error condition.  Values given did not resolve into a unique record.  Don't know what to edit
811 # should rarely occur (only if we use subfieldvalue with a value that exists twice, which is strange)
812         return -1;
813     }
814     else {
815         return $lastsubfieldid;
816     }
817 }
818
819 sub MARCfindsubfieldid {
820     my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
821     my $sth = $dbh->prepare( "select subfieldid from marc_subfield_table
822                                 where bibid=? and tag=? and tagorder=?
823                                         and subfieldcode=? and subfieldorder=?"
824     );
825     $sth->execute( $bibid, $tag, $tagorder, $subfield, $subfieldorder );
826     my ($res) = $sth->fetchrow;
827     unless ($res) {
828         $sth = $dbh->prepare( "select subfieldid from marc_subfield_table
829                                 where bibid=? and tag=? and tagorder=?
830                                         and subfieldcode=?"
831         );
832         $sth->execute( $bibid, $tag, $tagorder, $subfield );
833         ($res) = $sth->fetchrow;
834     }
835     return $res;
836 }
837
838 sub MARCfind_frameworkcode {
839     my ( $dbh, $bibid ) = @_;
840     my $sth =
841       $dbh->prepare("select frameworkcode from marc_biblio where bibid=?");
842     $sth->execute($bibid);
843     my ($frameworkcode) = $sth->fetchrow;
844     return $frameworkcode;
845 }
846
847 sub MARCdelsubfield {
848
849     # delete a subfield for $bibid / tag / tagorder / subfield / subfieldorder
850     my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
851         if ($subfieldorder) {
852                 $dbh->do( "delete from marc_subfield_table where bibid='$bibid' and
853                                 tag='$tag' and tagorder='$tagorder'
854                                 and subfieldcode='$subfield' and subfieldorder='$subfieldorder'
855                                 "
856                 );
857                 $dbh->do( "delete from marc_word where bibid='$bibid' and
858                                 tagsubfield='$tag$subfield' and tagorder='$tagorder'
859                                 and subfieldorder='$subfieldorder'
860                                 "
861                 );
862         } else {
863                 $dbh->do( "delete from marc_subfield_table where bibid='$bibid' and
864                                 tag='$tag' and tagorder='$tagorder'
865                                 and subfieldcode='$subfield'"
866                 );
867                 $dbh->do( "delete from marc_word where bibid='$bibid' and
868                                 tagsubfield='$tag$subfield' and tagorder='$tagorder'"
869                 );
870         }
871 }
872
873 sub MARCkoha2marcBiblio {
874
875     # this function builds partial MARC::Record from the old koha-DB fields
876     my ( $dbh, $biblionumber, $biblioitemnumber ) = @_;
877     my $sth =
878       $dbh->prepare(
879 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
880     );
881     my $record = MARC::Record->new();
882
883     #--- if bibid, then retrieve old-style koha data
884     if ( $biblionumber > 0 ) {
885         my $sth2 =
886           $dbh->prepare(
887 "select biblionumber,author,title,unititle,notes,abstract,serial,seriestitle,copyrightdate,timestamp
888                 from biblio where biblionumber=?"
889         );
890         $sth2->execute($biblionumber);
891         my $row = $sth2->fetchrow_hashref;
892         my $code;
893         foreach $code ( keys %$row ) {
894             if ( $row->{$code} ) {
895                 &MARCkoha2marcOnefield( $sth, $record, "biblio." . $code,
896                     $row->{$code}, '');
897             }
898         }
899     }
900
901     #--- if biblioitem, then retrieve old-style koha data
902     if ( $biblioitemnumber > 0 ) {
903         my $sth2 =
904           $dbh->prepare(
905             " SELECT biblioitemnumber,biblionumber,volume,number,classification,
906                                                 itemtype,url,isbn,issn,dewey,subclass,publicationyear,publishercode,
907                                                 volumedate,volumeddesc,timestamp,illus,pages,notes AS bnotes,size,place
908                                         FROM biblioitems
909                                         WHERE biblioitemnumber=?
910                                         "
911         );
912         $sth2->execute($biblioitemnumber);
913         my $row = $sth2->fetchrow_hashref;
914         my $code;
915         foreach $code ( keys %$row ) {
916             if ( $row->{$code} ) {
917                 &MARCkoha2marcOnefield( $sth, $record, "biblioitems." . $code,
918                     $row->{$code},'' );
919             }
920         }
921     }
922
923     # other fields => additional authors, subjects, subtitles
924     my $sth2 =
925       $dbh->prepare(
926         " SELECT author FROM additionalauthors WHERE biblionumber=?");
927     $sth2->execute($biblionumber);
928     while ( my $row = $sth2->fetchrow_hashref ) {
929         &MARCkoha2marcOnefield( $sth, $record, "additionalauthors.author",
930             $row->{'author'},'' );
931     }
932     $sth2 =
933       $dbh->prepare(" SELECT subject FROM bibliosubject WHERE biblionumber=?");
934     $sth2->execute($biblionumber);
935     while ( my $row = $sth2->fetchrow_hashref ) {
936         &MARCkoha2marcOnefield( $sth, $record, "bibliosubject.subject",
937             $row->{'subject'},'' );
938     }
939     $sth2 =
940       $dbh->prepare(
941         " SELECT subtitle FROM bibliosubtitle WHERE biblionumber=?");
942     $sth2->execute($biblionumber);
943     while ( my $row = $sth2->fetchrow_hashref ) {
944         &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
945             $row->{'subtitle'},'' );
946     }
947     return $record;
948 }
949
950 sub MARCkoha2marcItem {
951
952     # this function builds partial MARC::Record from the old koha-DB fields
953     my ( $dbh, $biblionumber, $itemnumber ) = @_;
954
955     #    my $dbh=&C4Connect;
956     my $sth =
957       $dbh->prepare(
958 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
959     );
960     my $record = MARC::Record->new();
961
962     #--- if item, then retrieve old-style koha data
963     if ( $itemnumber > 0 ) {
964
965         #       print STDERR "prepare $biblionumber,$itemnumber\n";
966         my $sth2 =
967           $dbh->prepare(
968 "SELECT itemnumber,biblionumber,multivolumepart,biblioitemnumber,barcode,dateaccessioned,
969                                                 booksellerid,homebranch,price,replacementprice,replacementpricedate,datelastborrowed,
970                                                 datelastseen,multivolume,stack,notforloan,itemlost,wthdrawn,itemcallnumber,issues,renewals,
971                                         reserves,restricted,binding,itemnotes,holdingbranch,timestamp
972                                         FROM items
973                                         WHERE itemnumber=?"
974         );
975         $sth2->execute($itemnumber);
976         my $row = $sth2->fetchrow_hashref;
977         my $code;
978         foreach $code ( keys %$row ) {
979             if ( $row->{$code} ) {
980                 &MARCkoha2marcOnefield( $sth, $record, "items." . $code,
981                     $row->{$code},'' );
982             }
983         }
984     }
985     return $record;
986 }
987
988 sub MARCkoha2marcSubtitle {
989
990     # this function builds partial MARC::Record from the old koha-DB fields
991     my ( $dbh, $bibnum, $subtitle ) = @_;
992     my $sth =
993       $dbh->prepare(
994 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
995     );
996     my $record = MARC::Record->new();
997     &MARCkoha2marcOnefield( $sth, $record, "bibliosubtitle.subtitle",
998         $subtitle,'' );
999     return $record;
1000 }
1001
1002 sub MARCkoha2marcOnefield {
1003     my ( $sth, $record, $kohafieldname, $value,$frameworkcode ) = @_;
1004     my $tagfield;
1005     my $tagsubfield;
1006     $sth->execute($frameworkcode,$kohafieldname);
1007     if ( ( $tagfield, $tagsubfield ) = $sth->fetchrow ) {
1008         if ( $record->field($tagfield) ) {
1009             my $tag = $record->field($tagfield);
1010             if ($tag) {
1011                 $tag->add_subfields( $tagsubfield, $value );
1012                 $record->delete_field($tag);
1013                 $record->add_fields($tag);
1014             }
1015         }
1016         else {
1017             $record->add_fields( $tagfield, " ", " ", $tagsubfield => $value );
1018         }
1019     }
1020     return $record;
1021 }
1022
1023 sub MARChtml2marc {
1024         my ($dbh,$rtags,$rsubfields,$rvalues,%indicators) = @_;
1025         my $prevtag = -1;
1026         my $record = MARC::Record->new();
1027 #       my %subfieldlist=();
1028         my $prevvalue; # if tag <10
1029         my $field; # if tag >=10
1030         for (my $i=0; $i< @$rtags; $i++) {
1031                 # rebuild MARC::Record
1032 #                       warn "0=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ";
1033                 if (@$rtags[$i] ne $prevtag) {
1034                         if ($prevtag < 10) {
1035                                 if ($prevvalue) {
1036                                         if ($prevtag ne '000') {
1037                                                 $record->add_fields((sprintf "%03s",$prevtag),$prevvalue);
1038                                         } else {
1039                                                 $record->leader($prevvalue);
1040                                         }
1041                                 }
1042                         } else {
1043                                 if ($field) {
1044                                         $record->add_fields($field);
1045                                 }
1046                         }
1047                         $indicators{@$rtags[$i]}.='  ';
1048                         if (@$rtags[$i] <10) {
1049                                 $prevvalue= @$rvalues[$i];
1050                                 undef $field;
1051                         } else {
1052                                 undef $prevvalue;
1053                                 $field = MARC::Field->new( (sprintf "%03s",@$rtags[$i]), substr($indicators{@$rtags[$i]},0,1),substr($indicators{@$rtags[$i]},1,1), @$rsubfields[$i] => @$rvalues[$i]);
1054 #                       warn "1=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
1055                         }
1056                         $prevtag = @$rtags[$i];
1057                 } else {
1058                         if (@$rtags[$i] <10) {
1059                                 $prevvalue=@$rvalues[$i];
1060                         } else {
1061                                 if (length(@$rvalues[$i])>0) {
1062                                         $field->add_subfields(@$rsubfields[$i] => @$rvalues[$i]);
1063 #                       warn "2=>".@$rtags[$i].@$rsubfields[$i]." = ".@$rvalues[$i].": ".$field->as_formatted;
1064                                 }
1065                         }
1066                         $prevtag= @$rtags[$i];
1067                 }
1068         }
1069         # the last has not been included inside the loop... do it now !
1070         $record->add_fields($field) if $field;
1071 #       warn "HTML2MARC=".$record->as_formatted;
1072         return $record;
1073 }
1074
1075 sub MARCmarc2koha {
1076         my ($dbh,$record,$frameworkcode) = @_;
1077         my $sth=$dbh->prepare("select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?");
1078         my $result;
1079         my $sth2=$dbh->prepare("SHOW COLUMNS from biblio");
1080         $sth2->execute;
1081         my $field;
1082         while (($field)=$sth2->fetchrow) {
1083                 $result=&MARCmarc2kohaOneField($sth,"biblio",$field,$record,$result,$frameworkcode);
1084         }
1085         $sth2=$dbh->prepare("SHOW COLUMNS from biblioitems");
1086         $sth2->execute;
1087         while (($field)=$sth2->fetchrow) {
1088                 if ($field eq 'notes') { $field = 'bnotes'; }
1089                 $result=&MARCmarc2kohaOneField($sth,"biblioitems",$field,$record,$result,$frameworkcode);
1090         }
1091         $sth2=$dbh->prepare("SHOW COLUMNS from items");
1092         $sth2->execute;
1093         while (($field)=$sth2->fetchrow) {
1094                 $result=&MARCmarc2kohaOneField($sth,"items",$field,$record,$result,$frameworkcode);
1095         }
1096         # additional authors : specific
1097         $result = &MARCmarc2kohaOneField($sth,"bibliosubtitle","subtitle",$record,$result,$frameworkcode);
1098         $result = &MARCmarc2kohaOneField($sth,"additionalauthors","additionalauthors",$record,$result,$frameworkcode);
1099 # modify copyrightdate to keep only the 1st year found
1100         my $temp = $result->{'copyrightdate'};
1101         $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
1102         if ($1>0) {
1103                 $result->{'copyrightdate'} = $1;
1104         } else { # if no cYYYY, get the 1st date.
1105                 $temp =~ m/(\d\d\d\d)/;
1106                 $result->{'copyrightdate'} = $1;
1107         }
1108 # modify publicationyear to keep only the 1st year found
1109         $temp = $result->{'publicationyear'};
1110         $temp =~ m/c(\d\d\d\d)/; # search cYYYY first
1111         if ($1>0) {
1112                 $result->{'publicationyear'} = $1;
1113         } else { # if no cYYYY, get the 1st date.
1114                 $temp =~ m/(\d\d\d\d)/;
1115                 $result->{'publicationyear'} = $1;
1116         }
1117         return $result;
1118 }
1119
1120 sub MARCmarc2kohaOneField {
1121
1122 # FIXME ? if a field has a repeatable subfield that is used in old-db, only the 1st will be retrieved...
1123     my ( $sth, $kohatable, $kohafield, $record, $result,$frameworkcode ) = @_;
1124     #    warn "kohatable / $kohafield / $result / ";
1125     my $res = "";
1126     my $tagfield;
1127     my $subfield;
1128     ( $tagfield, $subfield ) = MARCfind_marc_from_kohafield("",$kohatable.".".$kohafield,$frameworkcode);
1129     foreach my $field ( $record->field($tagfield) ) {
1130                 if ($field->tag()<10) {
1131                         if ($result->{$kohafield}) {
1132                                 $result->{$kohafield} .= " | ".$field->data();
1133                         } else {
1134                                 $result->{$kohafield} = $field->data();
1135                         }
1136                 } else {
1137                         if ( $field->subfields ) {
1138                                 my @subfields = $field->subfields();
1139                                 foreach my $subfieldcount ( 0 .. $#subfields ) {
1140                                         if ($subfields[$subfieldcount][0] eq $subfield) {
1141                                                 if ( $result->{$kohafield} ) {
1142                                                         $result->{$kohafield} .= " | " . $subfields[$subfieldcount][1];
1143                                                 }
1144                                                 else {
1145                                                         $result->{$kohafield} = $subfields[$subfieldcount][1];
1146                                                 }
1147                                         }
1148                                 }
1149                         }
1150                 }
1151     }
1152 #       warn "OneField for $kohatable.$kohafield and $frameworkcode=> $tagfield, $subfield";
1153     return $result;
1154 }
1155
1156 sub MARCaddword {
1157
1158     # split a subfield string and adds it into the word table.
1159     # removes stopwords
1160     my (
1161         $dbh,        $bibid,         $tag,    $tagorder,
1162         $subfieldid, $subfieldorder, $sentence
1163       )
1164       = @_;
1165     $sentence =~ s/(\.|\?|\:|\!|\'|,|\-|\"|\(|\)|\[|\]|\{|\}|\/)/ /g;
1166     my @words = split / /, $sentence;
1167     my $stopwords = C4::Context->stopwords;
1168     my $sth       =
1169       $dbh->prepare(
1170 "insert into marc_word (bibid, tagsubfield, tagorder, subfieldorder, word, sndx_word)
1171                         values (?,concat(?,?),?,?,?,soundex(?))"
1172     );
1173     foreach my $word (@words) {
1174 # we record only words one char long and not in stopwords hash
1175         if (length($word)>=1 and !($stopwords->{uc($word)})) {
1176             $sth->execute($bibid,$tag,$subfieldid,$tagorder,$subfieldorder,$word,$word);
1177             if ($sth->err()) {
1178                 warn "ERROR ==> insert into marc_word (bibid, tagsubfield, tagorder, subfieldorder, word, sndx_word) values ($bibid,concat($tag,$subfieldid),$tagorder,$subfieldorder,$word,soundex($word))\n";
1179             }
1180         }
1181     }
1182 }
1183
1184 sub MARCdelword {
1185
1186 # delete words. this sub deletes all the words from a sentence. a subfield modif is done by a delete then a add
1187     my ( $dbh, $bibid, $tag, $tagorder, $subfield, $subfieldorder ) = @_;
1188     my $sth =
1189       $dbh->prepare(
1190 "delete from marc_word where bibid=? and tagsubfield=concat(?,?) and tagorder=? and subfieldorder=?"
1191     );
1192     $sth->execute( $bibid, $tag, $subfield, $tagorder, $subfieldorder );
1193 }
1194
1195 #
1196 #
1197 # NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW
1198 #
1199 #
1200 # all the following subs are useful to manage MARC-DB with complete MARC records.
1201 # it's used with marcimport, and marc management tools
1202 #
1203
1204 =item ($bibid,$oldbibnum,$oldbibitemnum) = NEWnewbibilio($dbh,$MARCRecord,$oldbiblio,$oldbiblioitem);
1205
1206 creates a new biblio from a MARC::Record. The 3rd and 4th parameter are hashes and may be ignored. If only 2 params are passed to the sub, the old-db hashes
1207 are builded from the MARC::Record. If they are passed, they are used.
1208
1209 =item NEWnewitem($dbh, $record,$bibid);
1210
1211 adds an item in the db.
1212
1213 =cut
1214
1215 sub NEWnewbiblio {
1216     my ( $dbh, $record, $frameworkcode ) = @_;
1217     my $oldbibnum;
1218     my $oldbibitemnum;
1219     my $olddata = MARCmarc2koha( $dbh, $record,$frameworkcode );
1220     $oldbibnum = OLDnewbiblio( $dbh, $olddata );
1221         $olddata->{'biblionumber'} = $oldbibnum;
1222     $oldbibitemnum = OLDnewbiblioitem( $dbh, $olddata );
1223
1224     # search subtiles, addiauthors and subjects
1225     my ( $tagfield, $tagsubfield ) =
1226       MARCfind_marc_from_kohafield( $dbh, "additionalauthors.author",$frameworkcode );
1227     my @addiauthfields = $record->field($tagfield);
1228     foreach my $addiauthfield (@addiauthfields) {
1229         my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
1230         foreach my $subfieldcount ( 0 .. $#addiauthsubfields ) {
1231             OLDmodaddauthor( $dbh, $oldbibnum,
1232                 $addiauthsubfields[$subfieldcount] );
1233         }
1234     }
1235     ( $tagfield, $tagsubfield ) =
1236       MARCfind_marc_from_kohafield( $dbh, "bibliosubtitle.subtitle",$frameworkcode );
1237     my @subtitlefields = $record->field($tagfield);
1238     foreach my $subtitlefield (@subtitlefields) {
1239         my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1240         foreach my $subfieldcount ( 0 .. $#subtitlesubfields ) {
1241             OLDnewsubtitle( $dbh, $oldbibnum,
1242                 $subtitlesubfields[$subfieldcount] );
1243         }
1244     }
1245     ( $tagfield, $tagsubfield ) =
1246       MARCfind_marc_from_kohafield( $dbh, "bibliosubject.subject",$frameworkcode );
1247     my @subj = $record->field($tagfield);
1248     my @subjects;
1249     foreach my $subject (@subj) {
1250         my @subjsubfield = $subject->subfield($tagsubfield);
1251         foreach my $subfieldcount ( 0 .. $#subjsubfield ) {
1252             push @subjects, $subjsubfield[$subfieldcount];
1253         }
1254     }
1255     OLDmodsubject( $dbh, $oldbibnum, 1, @subjects );
1256
1257     # we must add bibnum and bibitemnum in MARC::Record...
1258     # we build the new field with biblionumber and biblioitemnumber
1259     # we drop the original field
1260     # we add the new builded field.
1261 # NOTE : Works only if the field is ONLY for biblionumber and biblioitemnumber
1262     # (steve and paul : thinks 090 is a good choice)
1263     my $sth =
1264       $dbh->prepare(
1265 "select tagfield,tagsubfield from marc_subfield_structure where kohafield=?"
1266     );
1267     $sth->execute("biblio.biblionumber");
1268     ( my $tagfield1, my $tagsubfield1 ) = $sth->fetchrow;
1269     $sth->execute("biblioitems.biblioitemnumber");
1270     ( my $tagfield2, my $tagsubfield2 ) = $sth->fetchrow;
1271         my $newfield;
1272         # biblionumber & biblioitemnumber are in different fields
1273     if ( $tagfield1 != $tagfield2 ) {
1274                 # deal with biblionumber
1275                 if ($tagfield1<10) {
1276                         $newfield = MARC::Field->new(
1277                                 $tagfield1, $oldbibnum,
1278                         );
1279                 } else {
1280                         $newfield = MARC::Field->new(
1281                                 $tagfield1, '', '', "$tagsubfield1" => $oldbibnum,
1282                         );
1283                 }
1284                 # drop old field and create new one...
1285                 my $old_field = $record->field($tagfield1);
1286                 $record->delete_field($old_field);
1287                 $record->add_fields($newfield);
1288                 # deal with biblioitemnumber
1289                 if ($tagfield2<10) {
1290                         $newfield = MARC::Field->new(
1291                                 $tagfield2, $oldbibitemnum,
1292                         );
1293                 } else {
1294                         $newfield = MARC::Field->new(
1295                                 $tagfield2, '', '', "$tagsubfield2" => $oldbibitemnum,
1296                         );
1297                 }
1298                 # drop old field and create new one...
1299                 $old_field = $record->field($tagfield2);
1300                 $record->delete_field($old_field);
1301                 $record->add_fields($newfield);
1302         # biblionumber & biblioitemnumber are in the same field (can't be <10 as fields <10 have only 1 value)
1303         } else {
1304                 my $newfield = MARC::Field->new(
1305                         $tagfield1, '', '', "$tagsubfield1" => $oldbibnum,
1306                         "$tagsubfield2" => $oldbibitemnum
1307                 );
1308                 # drop old field and create new one...
1309                 my $old_field = $record->field($tagfield1);
1310                 $record->delete_field($old_field);
1311                 $record->add_fields($newfield);
1312         }
1313 #       warn "REC : ".$record->as_formatted;
1314     my $bibid = MARCaddbiblio( $dbh, $record, $oldbibnum, $frameworkcode );
1315     return ( $bibid, $oldbibnum, $oldbibitemnum );
1316 }
1317
1318 sub NEWmodbiblioframework {
1319         my ($dbh,$bibid,$frameworkcode) =@_;
1320         my $sth = $dbh->prepare("Update marc_biblio SET frameworkcode=? WHERE bibid=$bibid");
1321         $sth->execute($frameworkcode);
1322         return 1;
1323 }
1324 sub NEWmodbiblio {
1325         my ($dbh,$record,$bibid,$frameworkcode) =@_;
1326         $frameworkcode="" unless $frameworkcode;
1327         &MARCmodbiblio($dbh,$bibid,$record,$frameworkcode,0);
1328         my $oldbiblio = MARCmarc2koha($dbh,$record,$frameworkcode);
1329         my $oldbiblionumber = OLDmodbiblio($dbh,$oldbiblio);
1330         OLDmodbibitem($dbh,$oldbiblio);
1331         # now, modify addi authors, subject, addititles.
1332         my ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"additionalauthors.author",$frameworkcode);
1333         my @addiauthfields = $record->field($tagfield);
1334         foreach my $addiauthfield (@addiauthfields) {
1335                 my @addiauthsubfields = $addiauthfield->subfield($tagsubfield);
1336                 foreach my $subfieldcount (0..$#addiauthsubfields) {
1337                         OLDmodaddauthor($dbh,$oldbiblionumber,$addiauthsubfields[$subfieldcount]);
1338                 }
1339         }
1340         ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubtitle.subtitle",$frameworkcode);
1341         my @subtitlefields = $record->field($tagfield);
1342         foreach my $subtitlefield (@subtitlefields) {
1343                 my @subtitlesubfields = $subtitlefield->subfield($tagsubfield);
1344                 # delete & create subtitle again because OLDmodsubtitle can't handle new subtitles
1345                 # between 2 modifs
1346                 $dbh->do("delete from bibliosubtitle where biblionumber=$oldbiblionumber");
1347                 foreach my $subfieldcount (0..$#subtitlesubfields) {
1348                         foreach my $subtit(split /\||#/,$subtitlesubfields[$subfieldcount]) {
1349                                 OLDnewsubtitle($dbh,$oldbiblionumber,$subtit);
1350                         }
1351                 }
1352         }
1353         ($tagfield,$tagsubfield) = MARCfind_marc_from_kohafield($dbh,"bibliosubject.subject",$frameworkcode);
1354         my @subj = $record->field($tagfield);
1355         my @subjects;
1356         foreach my $subject (@subj) {
1357                 my @subjsubfield = $subject->subfield($tagsubfield);
1358                 foreach my $subfieldcount (0..$#subjsubfield) {
1359                         push @subjects,$subjsubfield[$subfieldcount];
1360                 }
1361         }
1362         OLDmodsubject($dbh,$oldbiblionumber,1,@subjects);
1363         return 1;
1364 }
1365
1366 sub NEWdelbiblio {
1367     my ( $dbh, $bibid ) = @_;
1368     my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1369     &OLDdelbiblio( $dbh, $biblio );
1370     my $sth =
1371       $dbh->prepare(
1372         "select biblioitemnumber from biblioitems where biblionumber=?");
1373     $sth->execute($biblio);
1374     while ( my ($biblioitemnumber) = $sth->fetchrow ) {
1375         OLDdeletebiblioitem( $dbh, $biblioitemnumber );
1376     }
1377     &MARCdelbiblio( $dbh, $bibid, 0 );
1378 }
1379
1380 sub NEWnewitem {
1381     my ( $dbh, $record, $bibid ) = @_;
1382
1383     # add item in old-DB
1384         my $frameworkcode=MARCfind_frameworkcode($dbh,$bibid);
1385     my $item = &MARCmarc2koha( $dbh, $record,$frameworkcode );
1386     # needs old biblionumber and biblioitemnumber
1387     $item->{'biblionumber'} =
1388       MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1389     my $sth =
1390       $dbh->prepare(
1391         "select biblioitemnumber from biblioitems where biblionumber=?");
1392     $sth->execute( $item->{'biblionumber'} );
1393     ( $item->{'biblioitemnumber'} ) = $sth->fetchrow;
1394     my ( $itemnumber, $error ) = &OLDnewitems( $dbh, $item, $item->{barcode} );
1395
1396     # add itemnumber to MARC::Record before adding the item.
1397     $sth =
1398       $dbh->prepare(
1399 "select tagfield,tagsubfield from marc_subfield_structure where frameworkcode=? and kohafield=?"
1400     );
1401     &MARCkoha2marcOnefield( $sth, $record, "items.itemnumber", $itemnumber,$frameworkcode );
1402
1403     # add the item
1404     my $bib = &MARCadditem( $dbh, $record, $item->{'biblionumber'} );
1405 }
1406
1407 sub NEWmoditem {
1408     my ( $dbh, $record, $bibid, $itemnumber, $delete ) = @_;
1409     
1410         &MARCmoditem( $dbh, $record, $bibid, $itemnumber, $delete );
1411         my $frameworkcode=MARCfind_frameworkcode($dbh,$bibid);
1412     my $olditem = MARCmarc2koha( $dbh, $record,$frameworkcode );
1413     OLDmoditem( $dbh, $olditem );
1414 }
1415
1416 sub NEWdelitem {
1417     my ( $dbh, $bibid, $itemnumber ) = @_;
1418     my $biblio = &MARCfind_oldbiblionumber_from_MARCbibid( $dbh, $bibid );
1419     &OLDdelitem( $dbh, $itemnumber );
1420     &MARCdelitem( $dbh, $bibid, $itemnumber );
1421 }
1422
1423 #
1424 #
1425 # OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD
1426 #
1427 #
1428
1429 =item $biblionumber = OLDnewbiblio($dbh,$biblio);
1430
1431 adds a record in biblio table. Datas are in the hash $biblio.
1432
1433 =item $biblionumber = OLDmodbiblio($dbh,$biblio);
1434
1435 modify a record in biblio table. Datas are in the hash $biblio.
1436
1437 =item OLDmodsubtitle($dbh,$bibnum,$subtitle);
1438
1439 modify subtitles in bibliosubtitle table.
1440
1441 =item OLDmodaddauthor($dbh,$bibnum,$author);
1442
1443 adds or modify additional authors
1444 NOTE :  Strange sub : seems to delete MANY and add only ONE author... maybe buggy ?
1445
1446 =item $errors = OLDmodsubject($dbh,$bibnum, $force, @subject);
1447
1448 modify/adds subjects
1449
1450 =item OLDmodbibitem($dbh, $biblioitem);
1451
1452 modify a biblioitem
1453
1454 =item OLDmodnote($dbh,$bibitemnum,$note
1455
1456 modify a note for a biblioitem
1457
1458 =item OLDnewbiblioitem($dbh,$biblioitem);
1459
1460 adds a biblioitem ($biblioitem is a hash with the values)
1461
1462 =item OLDnewsubject($dbh,$bibnum);
1463
1464 adds a subject
1465
1466 =item OLDnewsubtitle($dbh,$bibnum,$subtitle);
1467
1468 create a new subtitle
1469
1470 =item ($itemnumber,$errors)= OLDnewitems($dbh,$item,$barcode);
1471
1472 create a item. $item is a hash and $barcode the barcode.
1473
1474 =item OLDmoditem($dbh,$item);
1475
1476 modify item
1477
1478 =item OLDdelitem($dbh,$itemnum);
1479
1480 delete item
1481
1482 =item OLDdeletebiblioitem($dbh,$biblioitemnumber);
1483
1484 deletes a biblioitem
1485 NOTE : not standard sub name. Should be OLDdelbiblioitem()
1486
1487 =item OLDdelbiblio($dbh,$biblio);
1488
1489 delete a biblio
1490
1491 =cut
1492
1493 sub OLDnewbiblio {
1494     my ( $dbh, $biblio ) = @_;
1495
1496     #  my $dbh    = &C4Connect;
1497     my $sth = $dbh->prepare("Select max(biblionumber) from biblio");
1498     $sth->execute;
1499     my $data   = $sth->fetchrow_arrayref;
1500     my $bibnum = $$data[0] + 1;
1501     my $series = 0;
1502
1503     if ( $biblio->{'seriestitle'} ) { $series = 1 }
1504     $sth->finish;
1505     $sth =
1506       $dbh->prepare(
1507 "insert into biblio set biblionumber  = ?, title = ?, author = ?, copyrightdate = ?, serial = ?, seriestitle = ?, notes = ?, abstract = ?, unititle = ?"
1508     );
1509     $sth->execute(
1510         $bibnum,             $biblio->{'title'},
1511         $biblio->{'author'}, $biblio->{'copyrightdate'},
1512         $biblio->{'serial'},             $biblio->{'seriestitle'},
1513         $biblio->{'notes'},  $biblio->{'abstract'},
1514                 $biblio->{'unititle'},
1515     );
1516
1517     $sth->finish;
1518
1519     #  $dbh->disconnect;
1520     return ($bibnum);
1521 }
1522
1523 sub OLDmodbiblio {
1524     my ( $dbh, $biblio ) = @_;
1525
1526     #  my $dbh   = C4Connect;
1527     my $query;
1528     my $sth;
1529
1530     $query = "";
1531     $sth   =
1532       $dbh->prepare(
1533 "Update biblio set title = ?, author = ?, abstract = ?, copyrightdate = ?, seriestitle = ?, serial = ?, unititle = ?, notes = ? where biblionumber = ?"
1534     );
1535     $sth->execute(
1536         $biblio->{'title'},       $biblio->{'author'},
1537         $biblio->{'abstract'},    $biblio->{'copyrightdate'},
1538         $biblio->{'seriestitle'}, $biblio->{'serial'},
1539         $biblio->{'unititle'},    $biblio->{'notes'},
1540         $biblio->{'biblionumber'}
1541     );
1542
1543     $sth->finish;
1544     return ( $biblio->{'biblionumber'} );
1545 }    # sub modbiblio
1546
1547 sub OLDmodsubtitle {
1548     my ( $dbh, $bibnum, $subtitle ) = @_;
1549     my $sth =
1550       $dbh->prepare(
1551         "update bibliosubtitle set subtitle = ? where biblionumber = ?");
1552     $sth->execute( $subtitle, $bibnum );
1553     $sth->finish;
1554 }    # sub modsubtitle
1555
1556 sub OLDmodaddauthor {
1557     my ( $dbh, $bibnum, @authors ) = @_;
1558
1559     #    my $dbh   = C4Connect;
1560     my $sth =
1561       $dbh->prepare("Delete from additionalauthors where biblionumber = ?");
1562
1563     $sth->execute($bibnum);
1564     $sth->finish;
1565     foreach my $author (@authors) {
1566         if ( $author ne '' ) {
1567             $sth =
1568               $dbh->prepare(
1569                 "Insert into additionalauthors set author = ?, biblionumber = ?"
1570             );
1571
1572             $sth->execute( $author, $bibnum );
1573
1574             $sth->finish;
1575         }    # if
1576     }
1577 }    # sub modaddauthor
1578
1579 sub OLDmodsubject {
1580     my ( $dbh, $bibnum, $force, @subject ) = @_;
1581
1582     #  my $dbh   = C4Connect;
1583     my $count = @subject;
1584     my $error;
1585     for ( my $i = 0 ; $i < $count ; $i++ ) {
1586         $subject[$i] =~ s/^ //g;
1587         $subject[$i] =~ s/ $//g;
1588         my $sth =
1589           $dbh->prepare(
1590 "select * from catalogueentry where entrytype = 's' and catalogueentry = ?"
1591         );
1592         $sth->execute( $subject[$i] );
1593
1594         if ( my $data = $sth->fetchrow_hashref ) {
1595         }
1596         else {
1597             if ( $force eq $subject[$i] || $force == 1 ) {
1598
1599                 # subject not in aut, chosen to force anway
1600                 # so insert into cataloguentry so its in auth file
1601                 my $sth2 =
1602                   $dbh->prepare(
1603 "Insert into catalogueentry (entrytype,catalogueentry) values ('s',?)"
1604                 );
1605
1606                 $sth2->execute( $subject[$i] ) if ( $subject[$i] );
1607                 $sth2->finish;
1608             }
1609             else {
1610                 $error =
1611                   "$subject[$i]\n does not exist in the subject authority file";
1612                 my $sth2 =
1613                   $dbh->prepare(
1614 "Select * from catalogueentry where entrytype = 's' and (catalogueentry like ? or catalogueentry like ? or catalogueentry like ?)"
1615                 );
1616                 $sth2->execute( "$subject[$i] %", "% $subject[$i] %",
1617                     "% $subject[$i]" );
1618                 while ( my $data = $sth2->fetchrow_hashref ) {
1619                     $error .= "<br>$data->{'catalogueentry'}";
1620                 }    # while
1621                 $sth2->finish;
1622             }    # else
1623         }    # else
1624         $sth->finish;
1625     }    # else
1626     if ( $error eq '' ) {
1627         my $sth =
1628           $dbh->prepare("Delete from bibliosubject where biblionumber = ?");
1629         $sth->execute($bibnum);
1630         $sth->finish;
1631         $sth =
1632           $dbh->prepare(
1633             "Insert into bibliosubject (subject,biblionumber) values (?,?)");
1634         my $query;
1635         foreach $query (@subject) {
1636             $sth->execute( $query, $bibnum ) if ( $query && $bibnum );
1637         }    # foreach
1638         $sth->finish;
1639     }    # if
1640
1641     #  $dbh->disconnect;
1642     return ($error);
1643 }    # sub modsubject
1644
1645 sub OLDmodbibitem {
1646     my ( $dbh, $biblioitem ) = @_;
1647     my $query;
1648
1649     $biblioitem->{'itemtype'}      = $dbh->quote( $biblioitem->{'itemtype'} );
1650     $biblioitem->{'url'}           = $dbh->quote( $biblioitem->{'url'} );
1651     $biblioitem->{'isbn'}          = $dbh->quote( $biblioitem->{'isbn'} );
1652     $biblioitem->{'issn'}          = $dbh->quote( $biblioitem->{'issn'} );
1653     $biblioitem->{'publishercode'} =
1654       $dbh->quote( $biblioitem->{'publishercode'} );
1655     $biblioitem->{'publicationyear'} =
1656       $dbh->quote( $biblioitem->{'publicationyear'} );
1657     $biblioitem->{'classification'} =
1658       $dbh->quote( $biblioitem->{'classification'} );
1659     $biblioitem->{'dewey'}       = $dbh->quote( $biblioitem->{'dewey'} );
1660     $biblioitem->{'subclass'}    = $dbh->quote( $biblioitem->{'subclass'} );
1661     $biblioitem->{'illus'}       = $dbh->quote( $biblioitem->{'illus'} );
1662     $biblioitem->{'pages'}       = $dbh->quote( $biblioitem->{'pages'} );
1663     $biblioitem->{'volumeddesc'} = $dbh->quote( $biblioitem->{'volumeddesc'} );
1664     $biblioitem->{'bnotes'}      = $dbh->quote( $biblioitem->{'bnotes'} );
1665     $biblioitem->{'size'}        = $dbh->quote( $biblioitem->{'size'} );
1666     $biblioitem->{'place'}       = $dbh->quote( $biblioitem->{'place'} );
1667
1668     $query = "Update biblioitems set
1669 itemtype        = $biblioitem->{'itemtype'},
1670 url             = $biblioitem->{'url'},
1671 isbn            = $biblioitem->{'isbn'},
1672 issn            = $biblioitem->{'issn'},
1673 publishercode   = $biblioitem->{'publishercode'},
1674 publicationyear = $biblioitem->{'publicationyear'},
1675 classification  = $biblioitem->{'classification'},
1676 dewey           = $biblioitem->{'dewey'},
1677 subclass        = $biblioitem->{'subclass'},
1678 illus           = $biblioitem->{'illus'},
1679 pages           = $biblioitem->{'pages'},
1680 volumeddesc     = $biblioitem->{'volumeddesc'},
1681 notes           = $biblioitem->{'bnotes'},
1682 size            = $biblioitem->{'size'},
1683 place           = $biblioitem->{'place'}
1684 where biblioitemnumber = $biblioitem->{'biblioitemnumber'}";
1685
1686     $dbh->do($query);
1687     if ( $dbh->errstr ) {
1688         warn "$query";
1689     }
1690 }    # sub modbibitem
1691
1692 sub OLDmodnote {
1693     my ( $dbh, $bibitemnum, $note ) = @_;
1694
1695     #  my $dbh=C4Connect;
1696     my $query = "update biblioitems set notes='$note' where
1697   biblioitemnumber='$bibitemnum'";
1698     my $sth = $dbh->prepare($query);
1699     $sth->execute;
1700     $sth->finish;
1701
1702     #  $dbh->disconnect;
1703 }
1704
1705 sub OLDnewbiblioitem {
1706     my ( $dbh, $biblioitem ) = @_;
1707
1708     #  my $dbh   = C4Connect;
1709     my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1710     my $data;
1711     my $bibitemnum;
1712
1713     $sth->execute;
1714     $data       = $sth->fetchrow_arrayref;
1715     $bibitemnum = $$data[0] + 1;
1716
1717     $sth->finish;
1718
1719     $sth = $dbh->prepare( "insert into biblioitems set
1720                                                                         biblioitemnumber = ?,           biblionumber     = ?,
1721                                                                         volume           = ?,                   number           = ?,
1722                                                                         classification  = ?,                    itemtype         = ?,
1723                                                                         url              = ?,                           isbn             = ?,
1724                                                                         issn             = ?,                           dewey            = ?,
1725                                                                         subclass         = ?,                           publicationyear  = ?,
1726                                                                         publishercode    = ?,           volumedate       = ?,
1727                                                                         volumeddesc      = ?,           illus            = ?,
1728                                                                         pages            = ?,                           notes            = ?,
1729                                                                         size             = ?,                           lccn             = ?,
1730                                                                         marc             = ?,                           place            = ?"
1731     );
1732     $sth->execute(
1733         $bibitemnum,                     $biblioitem->{'biblionumber'},
1734         $biblioitem->{'volume'},         $biblioitem->{'number'},
1735         $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1736         $biblioitem->{'url'},            $biblioitem->{'isbn'},
1737         $biblioitem->{'issn'},           $biblioitem->{'dewey'},
1738         $biblioitem->{'subclass'},       $biblioitem->{'publicationyear'},
1739         $biblioitem->{'publishercode'},  $biblioitem->{'volumedate'},
1740         $biblioitem->{'volumeddesc'},    $biblioitem->{'illus'},
1741         $biblioitem->{'pages'},          $biblioitem->{'bnotes'},
1742         $biblioitem->{'size'},           $biblioitem->{'lccn'},
1743         $biblioitem->{'marc'},           $biblioitem->{'place'}
1744     );
1745     $sth->finish;
1746
1747     #    $dbh->disconnect;
1748     return ($bibitemnum);
1749 }
1750
1751 sub OLDnewsubject {
1752     my ( $dbh, $bibnum ) = @_;
1753     my $sth =
1754       $dbh->prepare("insert into bibliosubject (biblionumber) values (?)");
1755     $sth->execute($bibnum);
1756     $sth->finish;
1757 }
1758
1759 sub OLDnewsubtitle {
1760     my ( $dbh, $bibnum, $subtitle ) = @_;
1761     my $sth =
1762       $dbh->prepare(
1763         "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1764     $sth->execute( $bibnum, $subtitle ) if $subtitle;
1765     $sth->finish;
1766 }
1767
1768 sub OLDnewitems {
1769     my ( $dbh, $item, $barcode ) = @_;
1770
1771     #  my $dbh   = C4Connect;
1772     my $sth = $dbh->prepare("Select max(itemnumber) from items");
1773     my $data;
1774     my $itemnumber;
1775     my $error = "";
1776
1777     $sth->execute;
1778     $data       = $sth->fetchrow_hashref;
1779     $itemnumber = $data->{'max(itemnumber)'} + 1;
1780     $sth->finish;
1781
1782 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1783     if ( $item->{'loan'} ) {
1784         $item->{'notforloan'} = $item->{'loan'};
1785     }
1786
1787     # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1788     if ( $item->{'dateaccessioned'} ) {
1789         $sth = $dbh->prepare( "Insert into items set
1790                                                         itemnumber           = ?,                       biblionumber         = ?,
1791                                                         multivolumepart      = ?,
1792                                                         biblioitemnumber     = ?,                       barcode              = ?,
1793                                                         booksellerid         = ?,                       dateaccessioned      = ?,
1794                                                         homebranch           = ?,                       holdingbranch        = ?,
1795                                                         price                = ?,                       replacementprice     = ?,
1796                                                         replacementpricedate = NOW(),           datelastseen            = NOW(),
1797                                                         multivolume                     = ?,                    stack                           = ?,
1798                                                         itemlost                        = ?,                    wthdrawn                        = ?,
1799                                                         paidfor                         = ?,                    itemnotes            = ?,
1800                                                         itemcallnumber  =?,                                                     notforloan = ?,
1801                                                         location = ?
1802                                                         "
1803         );
1804         $sth->execute(
1805                         $itemnumber,                            $item->{'biblionumber'},
1806                         $item->{'multivolumepart'},
1807                         $item->{'biblioitemnumber'},$barcode,
1808                         $item->{'booksellerid'},        $item->{'dateaccessioned'},
1809                         $item->{'homebranch'},          $item->{'holdingbranch'},
1810                         $item->{'price'},                       $item->{'replacementprice'},
1811                         $item->{multivolume},           $item->{stack},
1812                         $item->{itemlost},                      $item->{wthdrawn},
1813                         $item->{paidfor},                       $item->{'itemnotes'},
1814                         $item->{'itemcallnumber'},      $item->{'notforloan'},
1815                         $item->{'location'}
1816         );
1817     }
1818     else {
1819         $sth = $dbh->prepare( "Insert into items set
1820                                                         itemnumber           = ?,                       biblionumber         = ?,
1821                                                         multivolumepart      = ?,
1822                                                         biblioitemnumber     = ?,                       barcode              = ?,
1823                                                         booksellerid         = ?,                       dateaccessioned      = NOW(),
1824                                                         homebranch           = ?,                       holdingbranch        = ?,
1825                                                         price                = ?,                       replacementprice     = ?,
1826                                                         replacementpricedate = NOW(),           datelastseen            = NOW(),
1827                                                         multivolume                     = ?,                    stack                           = ?,
1828                                                         itemlost                        = ?,                    wthdrawn                        = ?,
1829                                                         paidfor                         = ?,                    itemnotes            = ?,
1830                                                         itemcallnumber  =?,                                                     notforloan = ?,
1831                                                         location = ?
1832                                                         "
1833         );
1834         $sth->execute(
1835                         $itemnumber,                            $item->{'biblionumber'},
1836                         $item->{'multivolumepart'},
1837                         $item->{'biblioitemnumber'},$barcode,
1838                         $item->{'booksellerid'},
1839                         $item->{'homebranch'},          $item->{'holdingbranch'},
1840                         $item->{'price'},                       $item->{'replacementprice'},
1841                         $item->{multivolume},           $item->{stack},
1842                         $item->{itemlost},                      $item->{wthdrawn},
1843                         $item->{paidfor},                       $item->{'itemnotes'},
1844                         $item->{'itemcallnumber'},      $item->{'notforloan'},
1845                         $item->{'location'}
1846         );
1847     }
1848     if ( defined $sth->errstr ) {
1849         $error .= $sth->errstr;
1850     }
1851     $sth->finish;
1852     return ( $itemnumber, $error );
1853 }
1854
1855 sub OLDmoditem {
1856     my ( $dbh, $item ) = @_;
1857     $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1858     my $query = "update items set  barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1859     my @bind = (
1860         $item->{'barcode'},                     $item->{'notes'},
1861         $item->{'itemcallnumber'},      $item->{'notforloan'},
1862         $item->{'location'},            $item->{multivolumepart},
1863                 $item->{multivolume},           $item->{stack},
1864                 $item->{wthdrawn},
1865     );
1866     if ( $item->{'lost'} ne '' ) {
1867         $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1868                                                         itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1869                                                         location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?";
1870         @bind = (
1871             $item->{'bibitemnum'},     $item->{'barcode'},
1872             $item->{'notes'},          $item->{'homebranch'},
1873             $item->{'lost'},           $item->{'wthdrawn'},
1874             $item->{'itemcallnumber'}, $item->{'notforloan'},
1875             $item->{'location'},                $item->{multivolumepart},
1876                         $item->{multivolume},           $item->{stack},
1877                         $item->{wthdrawn},
1878         );
1879                 if ($item->{homebranch}) {
1880                         $query.=",homebranch=?";
1881                         push @bind, $item->{homebranch};
1882                 }
1883                 if ($item->{holdingbranch}) {
1884                         $query.=",holdingbranch=?";
1885                         push @bind, $item->{holdingbranch};
1886                 }
1887     }
1888         $query.=" where itemnumber=?";
1889         push @bind,$item->{'itemnum'};
1890    if ( $item->{'replacement'} ne '' ) {
1891         $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1892     }
1893     my $sth = $dbh->prepare($query);
1894     $sth->execute(@bind);
1895     $sth->finish;
1896
1897     #  $dbh->disconnect;
1898 }
1899
1900 sub OLDdelitem {
1901     my ( $dbh, $itemnum ) = @_;
1902
1903     #  my $dbh=C4Connect;
1904     my $sth = $dbh->prepare("select * from items where itemnumber=?");
1905     $sth->execute($itemnum);
1906     my $data = $sth->fetchrow_hashref;
1907     $sth->finish;
1908     my $query = "Insert into deleteditems set ";
1909     my @bind  = ();
1910     foreach my $temp ( keys %$data ) {
1911         $query .= "$temp = ?,";
1912         push ( @bind, $data->{$temp} );
1913     }
1914     $query =~ s/\,$//;
1915
1916     #  print $query;
1917     $sth = $dbh->prepare($query);
1918     $sth->execute(@bind);
1919     $sth->finish;
1920     $sth = $dbh->prepare("Delete from items where itemnumber=?");
1921     $sth->execute($itemnum);
1922     $sth->finish;
1923
1924     #  $dbh->disconnect;
1925 }
1926
1927 sub OLDdeletebiblioitem {
1928     my ( $dbh, $biblioitemnumber ) = @_;
1929
1930     #    my $dbh   = C4Connect;
1931     my $sth = $dbh->prepare( "Select * from biblioitems
1932 where biblioitemnumber = ?"
1933     );
1934     my $results;
1935
1936     $sth->execute($biblioitemnumber);
1937
1938     if ( $results = $sth->fetchrow_hashref ) {
1939         $sth->finish;
1940         $sth =
1941           $dbh->prepare(
1942 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
1943                                         isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
1944                                         pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
1945         );
1946
1947         $sth->execute(
1948             $results->{biblioitemnumber}, $results->{biblionumber},
1949             $results->{volume},           $results->{number},
1950             $results->{classification},   $results->{itemtype},
1951             $results->{isbn},             $results->{issn},
1952             $results->{dewey},            $results->{subclass},
1953             $results->{publicationyear},  $results->{publishercode},
1954             $results->{volumedate},       $results->{volumeddesc},
1955             $results->{timestamp},        $results->{illus},
1956             $results->{pages},            $results->{notes},
1957             $results->{size},             $results->{url},
1958             $results->{lccn}
1959         );
1960         my $sth2 =
1961           $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
1962         $sth2->execute($biblioitemnumber);
1963         $sth2->finish();
1964     }    # if
1965     $sth->finish;
1966
1967     # Now delete all the items attached to the biblioitem
1968     $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
1969     $sth->execute($biblioitemnumber);
1970     my @results;
1971     while ( my $data = $sth->fetchrow_hashref ) {
1972         my $query = "Insert into deleteditems set ";
1973         my @bind  = ();
1974         foreach my $temp ( keys %$data ) {
1975             $query .= "$temp = ?,";
1976             push ( @bind, $data->{$temp} );
1977         }
1978         $query =~ s/\,$//;
1979         my $sth2 = $dbh->prepare($query);
1980         $sth2->execute(@bind);
1981     }    # while
1982     $sth->finish;
1983     $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
1984     $sth->execute($biblioitemnumber);
1985     $sth->finish();
1986
1987     #    $dbh->disconnect;
1988 }    # sub deletebiblioitem
1989
1990 sub OLDdelbiblio {
1991     my ( $dbh, $biblio ) = @_;
1992     my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
1993     $sth->execute($biblio);
1994     if ( my $data = $sth->fetchrow_hashref ) {
1995         $sth->finish;
1996         my $query = "Insert into deletedbiblio set ";
1997         my @bind  = ();
1998         foreach my $temp ( keys %$data ) {
1999             $query .= "$temp = ?,";
2000             push ( @bind, $data->{$temp} );
2001         }
2002
2003         #replacing the last , by ",?)"
2004         $query =~ s/\,$//;
2005         $sth = $dbh->prepare($query);
2006         $sth->execute(@bind);
2007         $sth->finish;
2008         $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
2009         $sth->execute($biblio);
2010         $sth->finish;
2011     }
2012     $sth->finish;
2013 }
2014
2015 #
2016 #
2017 # old functions
2018 #
2019 #
2020
2021 sub itemcount {
2022     my ($biblio) = @_;
2023     my $dbh = C4::Context->dbh;
2024
2025     #  print $query;
2026     my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
2027     $sth->execute($biblio);
2028     my $data = $sth->fetchrow_hashref;
2029     $sth->finish;
2030     return ( $data->{'count(*)'} );
2031 }
2032
2033 sub newbiblio {
2034     my ($biblio) = @_;
2035     my $dbh    = C4::Context->dbh;
2036     my $bibnum = OLDnewbiblio( $dbh, $biblio );
2037     # finds new (MARC bibid
2038     #   my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
2039     my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
2040     MARCaddbiblio( $dbh, $record, $bibnum,'' );
2041     return ($bibnum);
2042 }
2043
2044 =item modbiblio
2045
2046   $biblionumber = &modbiblio($biblio);
2047
2048 Update a biblio record.
2049
2050 C<$biblio> is a reference-to-hash whose keys are the fields in the
2051 biblio table in the Koha database. All fields must be present, not
2052 just the ones you wish to change.
2053
2054 C<&modbiblio> updates the record defined by
2055 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
2056
2057 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
2058 successful or not.
2059
2060 =cut
2061
2062 sub modbiblio {
2063         my ($biblio) = @_;
2064         my $dbh  = C4::Context->dbh;
2065         my $biblionumber=OLDmodbiblio($dbh,$biblio);
2066         my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
2067         # finds new (MARC bibid
2068         my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
2069         MARCmodbiblio($dbh,$bibid,$record,"",0);
2070         return($biblionumber);
2071 } # sub modbiblio
2072
2073 =item modsubtitle
2074
2075   &modsubtitle($biblionumber, $subtitle);
2076
2077 Sets the subtitle of a book.
2078
2079 C<$biblionumber> is the biblionumber of the book to modify.
2080
2081 C<$subtitle> is the new subtitle.
2082
2083 =cut
2084
2085 sub modsubtitle {
2086     my ( $bibnum, $subtitle ) = @_;
2087     my $dbh = C4::Context->dbh;
2088     &OLDmodsubtitle( $dbh, $bibnum, $subtitle );
2089 }    # sub modsubtitle
2090
2091 =item modaddauthor
2092
2093   &modaddauthor($biblionumber, $author);
2094
2095 Replaces all additional authors for the book with biblio number
2096 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
2097 C<&modaddauthor> deletes all additional authors.
2098
2099 =cut
2100
2101 sub modaddauthor {
2102     my ( $bibnum, @authors ) = @_;
2103     my $dbh = C4::Context->dbh;
2104     &OLDmodaddauthor( $dbh, $bibnum, @authors );
2105 }    # sub modaddauthor
2106
2107 =item modsubject
2108
2109   $error = &modsubject($biblionumber, $force, @subjects);
2110
2111 $force - a subject to force
2112
2113 $error - Error message, or undef if successful.
2114
2115 =cut
2116
2117 sub modsubject {
2118     my ( $bibnum, $force, @subject ) = @_;
2119     my $dbh = C4::Context->dbh;
2120     my $error = &OLDmodsubject( $dbh, $bibnum, $force, @subject );
2121     if ($error eq ''){
2122                 # When MARC is off, ensures that the MARC biblio table gets updated with new
2123                 # subjects, of course, it deletes the biblio in marc, and then recreates.
2124                 # This check is to ensure that no MARC data exists to lose.
2125                 if (C4::Context->preference("MARC") eq '0'){
2126                         my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
2127                         my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
2128                         &MARCmodbiblio($dbh,$bibid, $MARCRecord);
2129                 }
2130         }
2131         return ($error);
2132 }    # sub modsubject
2133
2134 sub modbibitem {
2135     my ($biblioitem) = @_;
2136     my $dbh = C4::Context->dbh;
2137     &OLDmodbibitem( $dbh, $biblioitem );
2138 }    # sub modbibitem
2139
2140 sub modnote {
2141     my ( $bibitemnum, $note ) = @_;
2142     my $dbh = C4::Context->dbh;
2143     &OLDmodnote( $dbh, $bibitemnum, $note );
2144 }
2145
2146 sub newbiblioitem {
2147     my ($biblioitem) = @_;
2148     my $dbh        = C4::Context->dbh;
2149     my $bibitemnum = &OLDnewbiblioitem( $dbh, $biblioitem );
2150
2151     my $MARCbiblio =
2152       MARCkoha2marcBiblio( $dbh, 0, $bibitemnum )
2153       ; # the 0 means "do NOT retrieve biblio, only biblioitem, in the MARC record
2154     my $bibid =
2155       &MARCfind_MARCbibid_from_oldbiblionumber( $dbh,
2156         $biblioitem->{biblionumber} );
2157     &MARCaddbiblio( $dbh, $MARCbiblio, $biblioitem->{biblionumber}, '',$bibid );
2158     return ($bibitemnum);
2159 }
2160
2161 sub newsubject {
2162     my ($bibnum) = @_;
2163     my $dbh = C4::Context->dbh;
2164     &OLDnewsubject( $dbh, $bibnum );
2165 }
2166
2167 sub newsubtitle {
2168     my ( $bibnum, $subtitle ) = @_;
2169     my $dbh = C4::Context->dbh;
2170     &OLDnewsubtitle( $dbh, $bibnum, $subtitle );
2171 }
2172
2173 sub newitems {
2174     my ( $item, @barcodes ) = @_;
2175     my $dbh = C4::Context->dbh;
2176     my $errors;
2177     my $itemnumber;
2178     my $error;
2179     foreach my $barcode (@barcodes) {
2180         ( $itemnumber, $error ) = &OLDnewitems( $dbh, $item, uc($barcode) );
2181         $errors .= $error;
2182         my $MARCitem =
2183           &MARCkoha2marcItem( $dbh, $item->{biblionumber}, $itemnumber );
2184         &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2185     }
2186     return ($errors);
2187 }
2188
2189 sub moditem {
2190     my ($item) = @_;
2191     my $dbh = C4::Context->dbh;
2192     &OLDmoditem( $dbh, $item );
2193     my $MARCitem =
2194       &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2195     my $bibid =
2196       &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2197     &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2198 }
2199
2200 sub checkitems {
2201     my ( $count, @barcodes ) = @_;
2202     my $dbh = C4::Context->dbh;
2203     my $error;
2204     my $sth = $dbh->prepare("Select * from items where barcode=?");
2205     for ( my $i = 0 ; $i < $count ; $i++ ) {
2206         $barcodes[$i] = uc $barcodes[$i];
2207         $sth->execute( $barcodes[$i] );
2208         if ( my $data = $sth->fetchrow_hashref ) {
2209             $error .= " Duplicate Barcode: $barcodes[$i]";
2210         }
2211     }
2212     $sth->finish;
2213     return ($error);
2214 }
2215
2216 sub countitems {
2217     my ($bibitemnum) = @_;
2218     my $dbh   = C4::Context->dbh;
2219     my $query = "";
2220     my $sth   =
2221       $dbh->prepare("Select count(*) from items where biblioitemnumber=?");
2222     $sth->execute($bibitemnum);
2223     my $data = $sth->fetchrow_hashref;
2224     $sth->finish;
2225     return ( $data->{'count(*)'} );
2226 }
2227
2228 sub delitem {
2229     my ($itemnum) = @_;
2230     my $dbh = C4::Context->dbh;
2231     &OLDdelitem( $dbh, $itemnum );
2232 }
2233
2234 sub deletebiblioitem {
2235     my ($biblioitemnumber) = @_;
2236     my $dbh = C4::Context->dbh;
2237     &OLDdeletebiblioitem( $dbh, $biblioitemnumber );
2238 }    # sub deletebiblioitem
2239
2240 sub delbiblio {
2241     my ($biblio) = @_;
2242     my $dbh = C4::Context->dbh;
2243     &OLDdelbiblio( $dbh, $biblio );
2244     my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2245     &MARCdelbiblio( $dbh, $bibid, 0 );
2246 }
2247
2248 sub getbiblio {
2249     my ($biblionumber) = @_;
2250     my $dbh = C4::Context->dbh;
2251     my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2252
2253     # || die "Cannot prepare $query\n" . $dbh->errstr;
2254     my $count = 0;
2255     my @results;
2256
2257     $sth->execute($biblionumber);
2258
2259     # || die "Cannot execute $query\n" . $sth->errstr;
2260     while ( my $data = $sth->fetchrow_hashref ) {
2261         $results[$count] = $data;
2262         $count++;
2263     }    # while
2264
2265     $sth->finish;
2266     return ( $count, @results );
2267 }    # sub getbiblio
2268
2269 sub getbiblioitem {
2270     my ($biblioitemnum) = @_;
2271     my $dbh = C4::Context->dbh;
2272     my $sth = $dbh->prepare( "Select * from biblioitems where
2273 biblioitemnumber = ?"
2274     );
2275     my $count = 0;
2276     my @results;
2277
2278     $sth->execute($biblioitemnum);
2279
2280     while ( my $data = $sth->fetchrow_hashref ) {
2281         $results[$count] = $data;
2282         $count++;
2283     }    # while
2284
2285     $sth->finish;
2286     return ( $count, @results );
2287 }    # sub getbiblioitem
2288
2289 sub getbiblioitembybiblionumber {
2290     my ($biblionumber) = @_;
2291     my $dbh = C4::Context->dbh;
2292     my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2293     my $count = 0;
2294     my @results;
2295
2296     $sth->execute($biblionumber);
2297
2298     while ( my $data = $sth->fetchrow_hashref ) {
2299         $results[$count] = $data;
2300         $count++;
2301     }    # while
2302
2303     $sth->finish;
2304     return ( $count, @results );
2305 }    # sub
2306
2307 sub getitemtypes {
2308     my $dbh   = C4::Context->dbh;
2309     my $query = "select * from itemtypes order by description";
2310     my $sth   = $dbh->prepare($query);
2311
2312     # || die "Cannot prepare $query" . $dbh->errstr;      
2313     my $count = 0;
2314     my @results;
2315
2316     $sth->execute;
2317
2318     # || die "Cannot execute $query\n" . $sth->errstr;
2319     while ( my $data = $sth->fetchrow_hashref ) {
2320         $results[$count] = $data;
2321         $count++;
2322     }    # while
2323
2324     $sth->finish;
2325     return ( $count, @results );
2326 }    # sub getitemtypes
2327
2328 sub getitemsbybiblioitem {
2329     my ($biblioitemnum) = @_;
2330     my $dbh = C4::Context->dbh;
2331     my $sth = $dbh->prepare( "Select * from items, biblio where
2332 biblio.biblionumber = items.biblionumber and biblioitemnumber
2333 = ?"
2334     );
2335
2336     # || die "Cannot prepare $query\n" . $dbh->errstr;
2337     my $count = 0;
2338     my @results;
2339
2340     $sth->execute($biblioitemnum);
2341
2342     # || die "Cannot execute $query\n" . $sth->errstr;
2343     while ( my $data = $sth->fetchrow_hashref ) {
2344         $results[$count] = $data;
2345         $count++;
2346     }    # while
2347
2348     $sth->finish;
2349     return ( $count, @results );
2350 }    # sub getitemsbybiblioitem
2351
2352 sub logchange {
2353
2354     # Subroutine to log changes to databases
2355 # Eventually, this subroutine will be used to create a log of all changes made,
2356     # with the possibility of "undo"ing some changes
2357     my $database = shift;
2358     if ( $database eq 'kohadb' ) {
2359         my $type     = shift;
2360         my $section  = shift;
2361         my $item     = shift;
2362         my $original = shift;
2363         my $new      = shift;
2364
2365         #       print STDERR "KOHA: $type $section $item $original $new\n";
2366     }
2367     elsif ( $database eq 'marc' ) {
2368         my $type        = shift;
2369         my $Record_ID   = shift;
2370         my $tag         = shift;
2371         my $mark        = shift;
2372         my $subfield_ID = shift;
2373         my $original    = shift;
2374         my $new         = shift;
2375
2376 #       print STDERR "MARC: $type $Record_ID $tag $mark $subfield_ID $original $new\n";
2377     }
2378 }
2379
2380 #------------------------------------------------
2381
2382 #---------------------------------------
2383 # Find a biblio entry, or create a new one if it doesn't exist.
2384 #  If a "subtitle" entry is in hash, add it to subtitle table
2385 sub getoraddbiblio {
2386
2387     # input params
2388     my (
2389         $dbh,       # db handle
2390                     # FIXME - Unused argument
2391         $biblio,    # hash ref to fields
2392     ) = @_;
2393
2394     # return
2395     my $biblionumber;
2396
2397     my $debug = 0;
2398     my $sth;
2399     my $error;
2400
2401     #-----
2402     $dbh = C4::Context->dbh;
2403
2404     print "<PRE>Looking for biblio </PRE>\n" if $debug;
2405     $sth = $dbh->prepare( "select biblionumber
2406                 from biblio
2407                 where title=? and author=?
2408                   and copyrightdate=? and seriestitle=?"
2409     );
2410     $sth->execute(
2411         $biblio->{title},     $biblio->{author},
2412         $biblio->{copyright}, $biblio->{seriestitle}
2413     );
2414     if ( $sth->rows ) {
2415         ($biblionumber) = $sth->fetchrow;
2416         print "<PRE>Biblio exists with number $biblionumber</PRE>\n" if $debug;
2417     }
2418     else {
2419
2420         # Doesn't exist.  Add new one.
2421         print "<PRE>Adding biblio</PRE>\n" if $debug;
2422         ( $biblionumber, $error ) = &newbiblio($biblio);
2423         if ($biblionumber) {
2424             print "<PRE>Added with biblio number=$biblionumber</PRE>\n"
2425               if $debug;
2426             if ( $biblio->{subtitle} ) {
2427                 &newsubtitle( $biblionumber, $biblio->{subtitle} );
2428             }    # if subtitle
2429         }
2430         else {
2431             print "<PRE>Couldn't add biblio: $error</PRE>\n" if $debug;
2432         }    # if added
2433     }
2434
2435     return $biblionumber, $error;
2436
2437 }    # sub getoraddbiblio
2438
2439 sub char_decode {
2440
2441     # converts ISO 5426 coded string to ISO 8859-1
2442     # sloppy code : should be improved in next issue
2443     my ( $string, $encoding ) = @_;
2444     $_ = $string;
2445
2446     #   $encoding = C4::Context->preference("marcflavour") unless $encoding;
2447     if ( $encoding eq "UNIMARC" ) {
2448 #         s/\xe1/Æ/gm;
2449         s/\xe2/Ð/gm;
2450         s/\xe9/Ø/gm;
2451         s/\xec/þ/gm;
2452         s/\xf1/æ/gm;
2453         s/\xf3/ð/gm;
2454         s/\xf9/ø/gm;
2455         s/\xfb/ß/gm;
2456         s/\xc1\x61/à/gm;
2457         s/\xc1\x65/è/gm;
2458         s/\xc1\x69/ì/gm;
2459         s/\xc1\x6f/ò/gm;
2460         s/\xc1\x75/ù/gm;
2461         s/\xc1\x41/À/gm;
2462         s/\xc1\x45/È/gm;
2463         s/\xc1\x49/Ì/gm;
2464         s/\xc1\x4f/Ò/gm;
2465         s/\xc1\x55/Ù/gm;
2466         s/\xc2\x41/Á/gm;
2467         s/\xc2\x45/É/gm;
2468         s/\xc2\x49/Í/gm;
2469         s/\xc2\x4f/Ó/gm;
2470         s/\xc2\x55/Ú/gm;
2471         s/\xc2\x59/Ý/gm;
2472         s/\xc2\x61/á/gm;
2473         s/\xc2\x65/é/gm;
2474         s/\xc2\x69/í/gm;
2475         s/\xc2\x6f/ó/gm;
2476         s/\xc2\x75/ú/gm;
2477         s/\xc2\x79/ý/gm;
2478         s/\xc3\x41/Â/gm;
2479         s/\xc3\x45/Ê/gm;
2480         s/\xc3\x49/Î/gm;
2481         s/\xc3\x4f/Ô/gm;
2482         s/\xc3\x55/Û/gm;
2483         s/\xc3\x61/â/gm;
2484         s/\xc3\x65/ê/gm;
2485         s/\xc3\x69/î/gm;
2486         s/\xc3\x6f/ô/gm;
2487         s/\xc3\x75/û/gm;
2488         s/\xc4\x41/Ã/gm;
2489         s/\xc4\x4e/Ñ/gm;
2490         s/\xc4\x4f/Õ/gm;
2491         s/\xc4\x61/ã/gm;
2492         s/\xc4\x6e/ñ/gm;
2493         s/\xc4\x6f/õ/gm;
2494         s/\xc8\x41/Ä/gm;
2495         s/\xc8\x45/Ë/gm;
2496         s/\xc8\x49/Ï/gm;
2497         s/\xc8\x61/ä/gm;
2498         s/\xc8\x65/ë/gm;
2499         s/\xc8\x69/ï/gm;
2500         s/\xc8\x6F/ö/gm;
2501         s/\xc8\x75/ü/gm;
2502         s/\xc8\x76/ÿ/gm;
2503         s/\xc9\x41/Ä/gm;
2504         s/\xc9\x45/Ë/gm;
2505         s/\xc9\x49/Ï/gm;
2506         s/\xc9\x4f/Ö/gm;
2507         s/\xc9\x55/Ü/gm;
2508         s/\xc9\x61/ä/gm;
2509         s/\xc9\x6f/ö/gm;
2510         s/\xc9\x75/ü/gm;
2511         s/\xca\x41/Å/gm;
2512         s/\xca\x61/å/gm;
2513         s/\xd0\x43/Ç/gm;
2514         s/\xd0\x63/ç/gm;
2515
2516         # this handles non-sorting blocks (if implementation requires this)
2517         $string = nsb_clean($_);
2518     }
2519     elsif ( $encoding eq "USMARC" || $encoding eq "MARC21" ) {
2520         if (/[\xc1-\xff]/) {
2521             s/\xe1\x61/à/gm;
2522             s/\xe1\x65/è/gm;
2523             s/\xe1\x69/ì/gm;
2524             s/\xe1\x6f/ò/gm;
2525             s/\xe1\x75/ù/gm;
2526             s/\xe1\x41/À/gm;
2527             s/\xe1\x45/È/gm;
2528             s/\xe1\x49/Ì/gm;
2529             s/\xe1\x4f/Ò/gm;
2530             s/\xe1\x55/Ù/gm;
2531             s/\xe2\x41/Á/gm;
2532             s/\xe2\x45/É/gm;
2533             s/\xe2\x49/Í/gm;
2534             s/\xe2\x4f/Ó/gm;
2535             s/\xe2\x55/Ú/gm;
2536             s/\xe2\x59/Ý/gm;
2537             s/\xe2\x61/á/gm;
2538             s/\xe2\x65/é/gm;
2539             s/\xe2\x69/í/gm;
2540             s/\xe2\x6f/ó/gm;
2541             s/\xe2\x75/ú/gm;
2542             s/\xe2\x79/ý/gm;
2543             s/\xe3\x41/Â/gm;
2544             s/\xe3\x45/Ê/gm;
2545             s/\xe3\x49/Î/gm;
2546             s/\xe3\x4f/Ô/gm;
2547             s/\xe3\x55/Û/gm;
2548             s/\xe3\x61/â/gm;
2549             s/\xe3\x65/ê/gm;
2550             s/\xe3\x69/î/gm;
2551             s/\xe3\x6f/ô/gm;
2552             s/\xe3\x75/û/gm;
2553             s/\xe4\x41/Ã/gm;
2554             s/\xe4\x4e/Ñ/gm;
2555             s/\xe4\x4f/Õ/gm;
2556             s/\xe4\x61/ã/gm;
2557             s/\xe4\x6e/ñ/gm;
2558             s/\xe4\x6f/õ/gm;
2559             s/\xe8\x45/Ë/gm;
2560             s/\xe8\x49/Ï/gm;
2561             s/\xe8\x65/ë/gm;
2562             s/\xe8\x69/ï/gm;
2563             s/\xe8\x76/ÿ/gm;
2564             s/\xe9\x41/Ä/gm;
2565             s/\xe9\x4f/Ö/gm;
2566             s/\xe9\x55/Ü/gm;
2567             s/\xe9\x61/ä/gm;
2568             s/\xe9\x6f/ö/gm;
2569             s/\xe9\x75/ü/gm;
2570             s/\xea\x41/Å/gm;
2571             s/\xea\x61/å/gm;
2572
2573             # this handles non-sorting blocks (if implementation requires this)
2574             $string = nsb_clean($_);
2575         }
2576     }
2577     return ($string);
2578 }
2579
2580 sub nsb_clean {
2581     my $NSB = '\x88';    # NSB : begin Non Sorting Block
2582     my $NSE = '\x89';    # NSE : Non Sorting Block end
2583                          # handles non sorting blocks
2584     my ($string) = @_;
2585     $_ = $string;
2586     s/$NSB/(/gm;
2587     s/[ ]{0,1}$NSE/) /gm;
2588     $string = $_;
2589     return ($string);
2590 }
2591
2592 sub FindDuplicate {
2593         my ($record)=@_;
2594         my $dbh = C4::Context->dbh;
2595         my $result = MARCmarc2koha($dbh,$record,'');
2596         my $sth;
2597         my ($biblionumber,$bibid,$title);
2598         # search duplicate on ISBN, easy and fast...
2599         if ($result->{isbn}) {
2600                 $sth = $dbh->prepare("select biblio.biblionumber,bibid,title from biblio,biblioitems,marc_biblio where biblio.biblionumber=biblioitems.biblionumber and marc_biblio.biblionumber=biblioitems.biblionumber and isbn=?");
2601                 $sth->execute($result->{'isbn'});
2602                 ($biblionumber,$bibid,$title) = $sth->fetchrow;
2603                 return $biblionumber,$bibid,$title if ($biblionumber);
2604         }
2605         # a more complex search : build a request for SearchMarc::catalogsearch()
2606         my (@tags, @and_or, @excluding, @operator, @value, $offset,$length);
2607         # search on biblio.title
2608         my ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.title","");
2609         if ($record->field($tag)) {
2610                 if ($record->field($tag)->subfields($subfield)) {
2611                         push @tags, "'".$tag.$subfield."'";
2612                         push @and_or, "and";
2613                         push @excluding, "";
2614                         push @operator, "contains";
2615                         push @value, $record->field($tag)->subfield($subfield);
2616 #                       warn "for title, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2617                 }
2618         }
2619         # ... and on biblio.author
2620         ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblio.author","");
2621         if ($record->field($tag)) {
2622                 if ($record->field($tag)->subfields($subfield)) {
2623                         push @tags, "'".$tag.$subfield."'";
2624                         push @and_or, "and";
2625                         push @excluding, "";
2626                         push @operator, "contains";
2627                         push @value, $record->field($tag)->subfield($subfield);
2628 #                       warn "for author, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2629                 }
2630         }
2631         # ... and on publicationyear.
2632         ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publicationyear","");
2633         if ($record->field($tag)) {
2634                 if ($record->field($tag)->subfields($subfield)) {
2635                         push @tags, "'".$tag.$subfield."'";
2636                         push @and_or, "and";
2637                         push @excluding, "";
2638                         push @operator, "=";
2639                         push @value, $record->field($tag)->subfield($subfield);
2640 #                       warn "for publicationyear, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2641                 }
2642         }
2643         # ... and on size.
2644         ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.size","");
2645         if ($record->field($tag)) {
2646                 if ($record->field($tag)->subfields($subfield)) {
2647                         push @tags, "'".$tag.$subfield."'";
2648                         push @and_or, "and";
2649                         push @excluding, "";
2650                         push @operator, "=";
2651                         push @value, $record->field($tag)->subfield($subfield);
2652 #                       warn "for size, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2653                 }
2654         }
2655         # ... and on publisher.
2656         ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.publishercode","");
2657         if ($record->field($tag)) {
2658                 if ($record->field($tag)->subfields($subfield)) {
2659                         push @tags, "'".$tag.$subfield."'";
2660                         push @and_or, "and";
2661                         push @excluding, "";
2662                         push @operator, "=";
2663                         push @value, $record->field($tag)->subfield($subfield);
2664 #                       warn "for publishercode, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2665                 }
2666         }
2667         # ... and on volume.
2668         ($tag,$subfield) = MARCfind_marc_from_kohafield($dbh,"biblioitems.volume","");
2669         if ($record->field($tag)) {
2670                 if ($record->field($tag)->subfields($subfield)) {
2671                         push @tags, "'".$tag.$subfield."'";
2672                         push @and_or, "and";
2673                         push @excluding, "";
2674                         push @operator, "=";
2675                         push @value, $record->field($tag)->subfield($subfield);
2676 #                       warn "for volume, I add $tag / $subfield".$record->field($tag)->subfield($subfield);
2677                 }
2678         }
2679
2680         my ($finalresult,$nbresult) = C4::SearchMarc::catalogsearch($dbh,\@tags,\@and_or,\@excluding,\@operator,\@value,0,10);
2681         # there is at least 1 result => return the 1st one
2682         if ($nbresult) {
2683 #               warn "$nbresult => ".@$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2684                 return @$finalresult[0]->{biblionumber},@$finalresult[0]->{bibid},@$finalresult[0]->{title};
2685         }
2686         # no result, returns nothing
2687         return;
2688 }
2689
2690 sub DisplayISBN {
2691         my ($isbn)=@_;
2692         my $seg1;
2693         if(substr($isbn, 0, 1) <=7) {
2694                 $seg1 = substr($isbn, 0, 1);
2695         } elsif(substr($isbn, 0, 2) <= 94) {
2696                 $seg1 = substr($isbn, 0, 2);
2697         } elsif(substr($isbn, 0, 3) <= 995) {
2698                 $seg1 = substr($isbn, 0, 3);
2699         } elsif(substr($isbn, 0, 4) <= 9989) {
2700                 $seg1 = substr($isbn, 0, 4);
2701         } else {
2702                 $seg1 = substr($isbn, 0, 5);
2703         }
2704         my $x = substr($isbn, length($seg1));
2705         my $seg2;
2706         if(substr($x, 0, 2) <= 19) {
2707 #               if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2708                 $seg2 = substr($x, 0, 2);
2709         } elsif(substr($x, 0, 3) <= 699) {
2710                 $seg2 = substr($x, 0, 3);
2711         } elsif(substr($x, 0, 4) <= 8399) {
2712                 $seg2 = substr($x, 0, 4);
2713         } elsif(substr($x, 0, 5) <= 89999) {
2714                 $seg2 = substr($x, 0, 5);
2715         } elsif(substr($x, 0, 6) <= 9499999) {
2716                 $seg2 = substr($x, 0, 6);
2717         } else {
2718                 $seg2 = substr($x, 0, 7);
2719         }
2720         my $seg3=substr($x,length($seg2));
2721         $seg3=substr($seg3,0,length($seg3)-1) ;
2722         my $seg4 = substr($x, -1, 1);
2723         return "$seg1-$seg2-$seg3-$seg4";
2724 }
2725
2726
2727 END { }    # module clean-up code here (global destructor)
2728
2729 =back
2730
2731 =head1 AUTHOR
2732
2733 Koha Developement team <info@koha.org>
2734
2735 Paul POULAIN paul.poulain@free.fr
2736
2737 =cut
2738
2739 # $Id$
2740 # $Log$
2741 # Revision 1.122  2005/08/04 13:27:48  tipaul
2742 # synch'ing 2.2 and head
2743 #
2744 # Revision 1.115.2.18  2005/08/02 07:45:44  tipaul
2745 # fix for bug http://bugs.koha.org/cgi-bin/bugzilla/show_bug.cgi?id=1009
2746 # (Not all items fields mapped to MARC)
2747 #
2748 # Revision 1.115.2.17  2005/08/01 15:15:43  tipaul
2749 # adding decoder for Ä string
2750 #
2751 # Revision 1.115.2.16  2005/07/28 19:56:15  tipaul
2752 # * removing a useless & CPU consuming call to MARCgetbiblio
2753 # * Leader management.
2754 # If you create a MARC tag "000", with a subfield '@', it will be managed as the leader.
2755 # Seems to work correctly.
2756 #
2757 # Now going to create a plugin for leader()
2758 #
2759 # Revision 1.115.2.15  2005/07/19 15:25:40  tipaul
2760 # * fixing a bug in subfield order when MARCgetbiblio
2761 # * getting rid with the limit "biblionumber & biblioitemnumber must be in the same tag". So, we can put biblionumber in 001 (field that has no subfields, so we can't put biblioitemnumber in this field), and use biblionumber as identifier in the MARC biblio too. Still to be deeply tested.
2762 # * adding some diacritic decoding (Ä, Ü...)
2763 #
2764 # Revision 1.115.2.14  2005/06/27 23:24:06  hdl
2765 # Display dashed ISBN
2766 #
2767 # Revision 1.115.2.13  2005/05/31 12:44:26  tipaul
2768 # patch from Genji (Waylon R.) to update subjects in MARC tables when systempref has MARC=OFF
2769 #
2770 # Revision 1.115.2.12  2005/05/30 11:22:41  tipaul
2771 # fixing a bug : when a field was repeated, the last field was also repeated. (Was due to the "empty" field in html between fields : to separate fields, in html, an empty field is automatically added. in MARChtml2marc, this empty field was not discarded correctly)
2772 #
2773 # Revision 1.115.2.11  2005/05/25 15:48:43  tipaul
2774 # * removing my for variables already declared
2775 # * updating biblio.unititle  field as well as other fields in biblio table
2776 #
2777 # Revision 1.115.2.10  2005/05/25 09:30:50  hdl
2778 # Adding NEWmodbiblioframework feature
2779 # Used by addbiblio.pl when modifying a framework selection.
2780 #
2781 # Revision 1.115.2.9  2005/04/07 10:05:25  tipaul
2782 # adding / to the list of symbols that are replace by spaces for searches
2783 #
2784 # Revision 1.115.2.8  2005/03/25 16:23:49  tipaul
2785 # some improvements :
2786 # * return immediatly when a subfield is empty
2787 # * search duplicate on isbn must be done only when there is an isbn ;-)
2788 #
2789 # Revision 1.115.2.7  2005/03/10 15:52:28  tipaul
2790 # * adding glass to opac marc detail.
2791 # * changing glasses behaviour : It now appears only on subfields that have a "link" value. Avoid useless glasses and removes nothing. **** WARNING **** : if you don't change you MARC parameters, glasses DISAPPEAR, because no subfields have a link value. So you MUST "reactivate" them manually. If you want to enable the search glass on field 225$a (collection in UNIMARC), just put 225a to "link" field (Koha >> parameters >> framework >> 225 field >> subfield >> modify $a >> enter 225a in link input field (without quotes or anything else)
2792 # * fixing bug with libopac
2793 #
2794 # Revision 1.115.2.6  2005/03/09 15:56:01  tipaul
2795 # Changing MARCmoditem to be like MARCmodbiblio : a modif is a delete & create.
2796 # Longer, but solves problems with repeated subfields.
2797 #
2798 # The previous version was not buggy except under certain circumstances (a repeated subfield, that does not exist usually in items)
2799 #
2800 # Revision 1.115.2.5  2005/02/24 13:54:04  tipaul
2801 # exporting MARCdelsubfield sub. It's used in authority merging.
2802 # Modifying it too to enable deletion of all subfields from a given tag/subfield or just one.
2803 #
2804 # Revision 1.115.2.4  2005/02/17 12:44:25  tipaul
2805 # bug in acquisition : the title was also stored as subtitle.
2806 #
2807 # Revision 1.115.2.3  2005/02/10 13:14:36  tipaul
2808 # * multiple main authors are now correctly handled in simple (non-MARC) view
2809 #
2810 # Revision 1.115.2.2  2005/01/11 16:02:35  tipaul
2811 # in catalogue, modifs were not stored properly the non-MARC item DB. Affect only libraries without barcodes.
2812 #
2813 # Revision 1.115.2.1  2005/01/11 14:45:37  tipaul
2814 # bugfix : issn were not stored correctly in non-MARC DB on biblio modification
2815 #
2816 # Revision 1.115  2005/01/06 14:32:17  tipaul
2817 # improvement of speed for bulkmarcimport.
2818 # A sub had been forgotten to use the C4::Context->marcfromkohafield array, that caches DB datas.
2819 # this is only a little improvement for normal DB modif, but almost x2 the speed of bulkmarcimport... from 6records/seconds to more than 10.
2820 #
2821 # Revision 1.114  2005/01/03 10:48:33  tipaul
2822 # * bugfix for the search on a MARC detail, when you clic on the magnifying glass (caused an internal server error)
2823 # * partial support of the "linkage" MARC feature : if you enter a "link" on a MARC subfield, the magnifying glass won't search on the field, but on the linked field. I agree it's a partial support. Will be improved, but I need to investigate MARC21 & UNIMARC diffs on this topic.
2824 #
2825 # Revision 1.113  2004/12/10 16:27:53  tipaul
2826 # limiting the number of search term to 8. There was no limit before, but 8 words seems to be the upper limit mySQL can deal with (in less than a second. tested on a DB with 13 000 items)
2827 # In 2.4, a new DB structure will highly speed things and this limit will be removed.
2828 # FindDuplicate is activated again, the perf problems were due to this problem.
2829 #
2830 # Revision 1.112  2004/12/08 10:14:42  tipaul
2831 # * desactivate FindDuplicate
2832 # * fix from Genji
2833 #
2834 # Revision 1.111  2004/11/25 17:39:44  tipaul
2835 # removing useless &branches in package declaration
2836 #
2837 # Revision 1.110  2004/11/24 16:00:01  tipaul
2838 # removing sub branches (commited by chris for MARC=OFF bugfix, but sub branches is already in Acquisition.pm)
2839 #
2840 # Revision 1.109  2004/11/24 15:58:31  tipaul
2841 # * critical fix for acquisition (see RC3 release notes)
2842 # * critical fix for duplicate finder
2843 #
2844 # Revision 1.108  2004/11/19 19:41:22  rangi
2845 # Shifting branches() from deprecated C4::Catalogue to C4::Biblio
2846 # Allowing the non marc interface acquisitions to work.
2847 #
2848 # Revision 1.107  2004/11/05 10:15:27  tipaul
2849 # Improving FindDuplicate to find duplicate records on adding biblio
2850 #
2851 # Revision 1.106  2004/11/02 16:44:45  tipaul
2852 # new feature : checking for duplicate biblio.
2853 #
2854 # For instance, it's only done on ISBN only. Will be improved soon.
2855 #
2856 # When a duplicate is detected, the biblio is not saved, but the user is asked for a confirmations.
2857 #
2858 # Revision 1.105  2004/09/23 16:15:37  tipaul
2859 # indenting diff
2860 #
2861 # Revision 1.104  2004/09/16 15:06:46  tipaul
2862 # enabling # (| still possible too) for repeatable subfields
2863 #
2864 # Revision 1.103  2004/09/06 14:17:34  tipaul
2865 # some commented warning added + 1 major bugfix => drop empty fields, NOT fields containing 0
2866 #
2867 # Revision 1.102  2004/09/06 10:00:19  tipaul
2868 # adding a "location" field to the library.
2869 # This field is useful when the callnumber contains no information on the room where the item is stored.
2870 # With this field, we now have 3 levels of informations to find a book :
2871 # * the branch.
2872 # * the location.
2873 # * the callnumber.
2874 #
2875 # This should be versatile enough to solve any storing method.
2876 # This hack is quite simple, due to the nice Biblio.pm API. The MARC => koha db link is automatically managed. Just add the link in the parameters section.
2877 #
2878 # Revision 1.101  2004/08/18 16:01:37  tipaul
2879 # modifs to support frameworkcodes
2880 #
2881 # Revision 1.100  2004/08/13 16:37:25  tipaul
2882 # adding frameworkcode to API in some subs
2883 #
2884 # Revision 1.99  2004/07/30 13:54:50  doxulting
2885 # Beginning of serial commit
2886 #
2887 # Revision 1.98  2004/07/15 09:48:10  tipaul
2888 # * removing useless sub
2889 # * minor bugfix in moditem (managing homebranch & holdingbranch)
2890 #
2891 # Revision 1.97  2004/07/02 15:53:53  tipaul
2892 # bugfix (due to frameworkcode field)
2893 #
2894 # Revision 1.96  2004/06/29 16:07:10  tipaul
2895 # last sync for 2.1.0 release
2896 #
2897 # Revision 1.95  2004/06/26 23:19:59  rangi
2898 # Fixing modaddauthor, and adding getitemtypes.
2899 # Also tidying up formatting of code
2900 #
2901 # Revision 1.94  2004/06/17 08:16:32  tipaul
2902 # merging tag & subfield in marc_word for better perfs
2903 #
2904 # Revision 1.93  2004/06/11 15:38:06  joshferraro
2905 # Changes MARCaddword to index words >= 1 char ... needed for more accurate
2906 # searches using SearchMarc routines.
2907 #
2908 # Revision 1.92  2004/06/10 08:29:01  tipaul
2909 # MARC authority management (continued)
2910 #
2911 # Revision 1.91  2004/06/03 10:03:01  tipaul
2912 # * frameworks and itemtypes are independant
2913 # * in the MARC editor, showing the + to duplicate a tag only if the tag is repeatable
2914 #
2915 # Revision 1.90  2004/05/28 08:25:53  tipaul
2916 # hidding hidden & isurl constraints into MARC subfield structure
2917 #
2918 # Revision 1.89  2004/05/27 21:47:21  rangi
2919 # Fix for bug 787
2920 #
2921 # Revision 1.88  2004/05/18 15:23:49  tipaul
2922 # framework management : 1 MARC framework for each itemtype
2923 #
2924 # Revision 1.87  2004/05/18 11:54:07  tipaul
2925 # getitemtypes moved in Koha.pm
2926 #
2927 # Revision 1.86  2004/05/03 09:19:22  tipaul
2928 # some fixes for mysql prepare & execute
2929 #
2930 # Revision 1.85  2004/04/02 14:55:48  tipaul
2931 # renaming items.bulk field to items.itemcallnumber.
2932 # Will be used to store call number for libraries that don't use dewey classification.
2933 # Note it's related to ITEMS, not biblio.
2934 #
2935 # Revision 1.84  2004/03/24 17:18:30  joshferraro
2936 # Fixes bug 749 by removing the comma on line 1488.
2937 #
2938 # Revision 1.83  2004/03/15 14:31:50  tipaul
2939 # adding a minor check
2940 #
2941 # Revision 1.82  2004/03/07 05:47:31  acli
2942 # Various updates/fixes from rel_2_0
2943 # Fixes for bugs 721 (templating), 727, and 734
2944 #
2945 # Revision 1.81  2004/03/06 20:26:13  tipaul
2946 # adding seealso feature in MARC searches
2947 #
2948 # Revision 1.80  2004/02/12 13:40:56  tipaul
2949 # deleting subs duplicated by error
2950 #
2951 # Revision 1.79  2004/02/11 08:40:09  tipaul
2952 # synch'ing 2.0.0 branch and head
2953 #
2954 # Revision 1.78.2.3  2004/02/10 13:15:46  tipaul
2955 # removing 2 warnings
2956 #
2957 # Revision 1.78.2.2  2004/01/26 10:38:06  tipaul
2958 # dealing correctly "bulk" field
2959 #
2960 # Revision 1.78.2.1  2004/01/13 17:29:53  tipaul
2961 # * minor html fixes
2962 # * adding publisher in acquisition process (& ordering basket by publisher)
2963 #
2964 # Revision 1.78  2003/12/09 15:57:28  tipaul
2965 # rolling back to working char_decode sub
2966 #
2967 # Revision 1.77  2003/12/03 17:47:14  tipaul
2968 # bugfixes for biblio deletion
2969 #
2970 # Revision 1.76  2003/12/03 01:43:41  slef
2971 # conflict markers?
2972 #
2973 # Revision 1.75  2003/12/03 01:42:03  slef
2974 # bug 662 fixes securing DBI
2975 #
2976 # Revision 1.74  2003/11/28 09:48:33  tipaul
2977 # bugfix : misusing prepare & execute => now using prepare(?) and execute($var)
2978 #
2979 # Revision 1.73  2003/11/28 09:45:25  tipaul
2980 # bugfix for iso2709 file import in the "notforloan" field.
2981 #
2982 # But notforloan field called "loan" somewhere, so in case "loan" is used, copied to "notforloan" to avoid a bug.
2983 #
2984 # Revision 1.72  2003/11/24 17:40:14  tipaul
2985 # fix for #385
2986 #
2987 # Revision 1.71  2003/11/24 16:28:49  tipaul
2988 # biblio & item deletion now works fine in MARC editor.
2989 # Stores deleted biblio/item in the marc field of the deletedbiblio/deleteditem table.
2990 #
2991 # Revision 1.70  2003/11/24 13:29:55  tipaul
2992 # moving $id from beginning to end of file (70 commits... huge comments...)
2993 #
2994 # Revision 1.69  2003/11/24 13:27:17  tipaul
2995 # fix for #380 (bibliosubject)
2996 #
2997 # Revision 1.68  2003/11/06 17:18:30  tipaul
2998 # bugfix for #384
2999 #
3000 # 1st draft for MARC biblio deletion.
3001 # Still does not work well, but at least, Biblio.pm compiles & it should'nt break too many things
3002 # (Note the trash in the MARCdetail, but don't use it, please :-) )
3003 #
3004 # Revision 1.67  2003/10/25 08:46:27  tipaul
3005 # minor fixes for bilbio deletion (still buggy)
3006 #
3007 # Revision 1.66  2003/10/17 10:02:56  tipaul
3008 # Indexing only words longer than 2 letters. Was >=2 before, & 2 letters words usually means nothing.
3009 #
3010 # Revision 1.65  2003/10/14 09:45:29  tipaul
3011 # adding rebuildnonmarc.pl script : run this script when you change a link between marc and non MARC DB. It rebuilds the non-MARC DB (long operation)
3012 #
3013 # Revision 1.64  2003/10/06 15:20:51  tipaul
3014 # fix for 536 (subtitle error)
3015 #
3016 # Revision 1.63  2003/10/01 13:25:49  tipaul
3017 # seems a char encoding problem modified something in char_decode sub... changing back to something that works...
3018 #
3019 # Revision 1.62  2003/09/17 14:21:13  tipaul
3020 # fixing bug that makes a MARC biblio disappear when using full acquisition (order => recieve ==> MARC editor).
3021 # Before this 2 lines fix, the MARC biblio was deleted during recieve, and had to be entirely recreated :-(
3022 #
3023 # Revision 1.61  2003/09/17 10:24:39  tipaul
3024 # notforloan value in itemtype was overwritting notforloan value in a given item.
3025 # I changed this behaviour :
3026 # if notforloan is set for a given item, and NOT for all items from this itemtype, the notforloan is kept.
3027 # If notforloan is set for itemtype, it's used (and impossible to loan a specific item from this itemtype)
3028 #
3029 # Revision 1.60  2003/09/04 14:11:23  tipaul
3030 # fix for 593 (data duplication in MARC-DB)
3031 #
3032 # Revision 1.58  2003/08/06 12:54:52  tipaul
3033 # fix for publicationyear : extracting numeric value from MARC string, like for copyrightdate.
3034 # (note that copyrightdate still extracted to get numeric format)
3035 #
3036 # Revision 1.57  2003/07/15 23:09:18  slef
3037 # change show columns to use biblioitems bnotes too
3038 #
3039 # Revision 1.56  2003/07/15 11:34:52  slef
3040 # fixes from paul email
3041 #
3042 # Revision 1.55  2003/07/15 00:02:49  slef
3043 # Work on bug 515... can we do a single-side rename of notes to bnotes?
3044 #
3045 # Revision 1.54  2003/07/11 11:51:32  tipaul
3046 # *** empty log message ***
3047 #
3048 # Revision 1.52  2003/07/10 10:37:19  tipaul
3049 # fix for copyrightdate problem, #514
3050 #
3051 # Revision 1.51  2003/07/02 14:47:17  tipaul
3052 # fix for #519 : items.dateaccessioned imports incorrectly
3053 #
3054 # Revision 1.49  2003/06/17 11:21:13  tipaul
3055 # improvments/fixes for z3950 support.
3056 # * Works now even on ADD, not only on MODIFY
3057 # * able to search on ISBN, author, title
3058 #
3059 # Revision 1.48  2003/06/16 09:22:53  rangi
3060 # Just added an order clause to getitemtypes
3061 #
3062 # Revision 1.47  2003/05/20 16:22:44  tipaul
3063 # fixing typo in Biblio.pm POD
3064 #
3065 # Revision 1.46  2003/05/19 13:45:18  tipaul
3066 # support for subtitles, additional authors, subject.
3067 # This supports is only for MARC <-> OLD-DB link. It worked previously, but values entered as MARC were not reported to OLD-DB, neither values entered as OLD-DB were reported to MARC.
3068 # Note that some OLD-DB subs are strange (dummy ?) see OLDmodsubject, OLDmodsubtitle, OLDmodaddiauthor in C4/Biblio.pm
3069 # For example it seems impossible to have more that 1 addi author and 1 subtitle. In MARC it's not the case. So, if you enter more than one, I'm afraid only the LAST will be stored.
3070 #
3071 # Revision 1.45  2003/04/29 16:50:49  tipaul
3072 # really proud of this commit :-)
3073 # z3950 search and import seems to works fine.
3074 # Let me explain how :
3075 # * a "search z3950" button is added in the addbiblio template.
3076 # * when clicked, a popup appears and z3950/search.pl is called
3077 # * z3950/search.pl calls addz3950search in the DB
3078 # * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table.
3079 # * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending.
3080 # * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled
3081 #
3082 # Note :
3083 # * character encoding support : (It's a nightmare...) In the z3950servers table, a "encoding" column has been added. You can put "UNIMARC" or "USMARC" in this column. Depending on this, the char_decode in C4::Biblio.pm replaces marc-char-encode by an iso 8859-1 encoding. Note that in the breeding import this value has been added too, for a better support.
3084 # * the marc_breeding and z3950* tables have been modified : they have an encoding column and the random z3950 number is stored too for convenience => it's the key I use to list only requested biblios in the popup.
3085 #
3086 # Revision 1.44  2003/04/28 13:07:14  tipaul
3087 # Those fixes solves the "internal server error" with MARC::Record 1.12.
3088 # It was due to an illegal contruction in Koha : we tried to retrive subfields from <10 tags.
3089 # That's not possible. MARC::Record accepted this in 0.93 version, but it was fixed after.
3090 # Now, the construct/retrieving is OK !
3091 #
3092 # Revision 1.43  2003/04/10 13:56:02  tipaul
3093 # Fix some bugs :
3094 # * worked in 1.9.0, but not in 1.9.1 :
3095 # - modif of a biblio didn't work
3096 # - empty fields where not shown when modifying a biblio. empty fields managed by the library (ie in tab 0->9 in MARC parameter table) MUST be entered, even if not presented.
3097 #
3098 # * did not work before :
3099 # - repeatable subfields now works correctly. Enter 2 subfields separated by | and they will be splitted during saving.
3100 # - dropped the last subfield of the MARC form :-(
3101 #
3102 # Internal changes :
3103 # - MARCmodbiblio now works by deleting and recreating the biblio. It's not perf optimized, but MARC is a "do_something_impossible_to_trace" standard, so, it's the best solution. not a problem for me, as biblio are rarely modified.
3104 # Note the MARCdelbiblio has been rewritted to enable deletion of a biblio WITHOUT deleting items.
3105 #
3106 # Revision 1.42  2003/04/04 08:41:11  tipaul
3107 # last commits before 1.9.1
3108 #
3109 # Revision 1.41  2003/04/01 12:26:43  tipaul
3110 # fixes
3111 #
3112 # Revision 1.40  2003/03/11 15:14:03  tipaul
3113 # pod updating
3114 #
3115 # Revision 1.39  2003/03/07 16:35:42  tipaul
3116 # * moving generic functions to Koha.pm
3117 # * improvement of SearchMarc.pm
3118 # * bugfixes
3119 # * code cleaning
3120 #
3121 # Revision 1.38  2003/02/27 16:51:59  tipaul
3122 # * moving prepare / execute to ? form.
3123 # * some # cleaning
3124 # * little bugfix.
3125 # * road to 1.9.2 => acquisition and cataloguing merging
3126 #
3127 # Revision 1.37  2003/02/12 11:03:03  tipaul
3128 # Support for 000 -> 010 fields.
3129 # Those fields doesn't have subfields.
3130 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3131 # Note it's only virtual : when rebuilding the MARC::Record, the koha API handle correctly "@" subfields => the resulting MARC record has a 00x field without subfield.
3132 #
3133 # Revision 1.36  2003/02/12 11:01:01  tipaul
3134 # Support for 000 -> 010 fields.
3135 # Those fields doesn't have subfields.
3136 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3137 # Note it's only virtual : when rebuilding the MARC::Record, the koha API handle correctly "@" subfields => the resulting MARC record has a 00x field without subfield.
3138 #
3139 # Revision 1.35  2003/02/03 18:46:00  acli
3140 # Minor factoring in C4/Biblio.pm, plus change to export the per-tag
3141 # 'mandatory' property to a per-subfield 'tag_mandatory' template parameter,
3142 # so that addbiblio.tmpl can distinguish between mandatory subfields in a
3143 # mandatory tag and mandatory subfields in an optional tag
3144 #
3145 # Not-minor factoring in acqui.simple/addbiblio.pl to make the if-else blocks
3146 # smaller, and to add some POD; need further testing for this
3147 #
3148 # Added function to check if a MARC subfield name is "koha-internal" (instead
3149 # of checking it for 'lib' and 'tag' everywhere); temporarily added to Koha.pm
3150 #
3151 # Use above function in acqui.simple/additem.pl and search.marc/search.pl
3152 #
3153 # Revision 1.34  2003/01/28 14:50:04  tipaul
3154 # fixing MARCmodbiblio API and reindenting code
3155 #
3156 # Revision 1.33  2003/01/23 12:22:37  tipaul
3157 # adding char_decode to decode MARC21 or UNIMARC extended chars
3158 #
3159 # Revision 1.32  2002/12/16 15:08:50  tipaul
3160 # small but important bugfix (fixes a problem in export)
3161 #
3162 # Revision 1.31  2002/12/13 16:22:04  tipaul
3163 # 1st draft of marc export
3164 #
3165 # Revision 1.30  2002/12/12 21:26:35  tipaul
3166 # YAB ! (Yet Another Bugfix) => related to biblio modif
3167 # (some warning cleaning too)
3168 #
3169 # Revision 1.29  2002/12/12 16:35:00  tipaul
3170 # adding authentification with Auth.pm and
3171 # MAJOR BUGFIX on marc biblio modification
3172 #
3173 # Revision 1.28  2002/12/10 13:30:03  tipaul
3174 # fugfixes from Dombes Abbey work
3175 #
3176 # Revision 1.27  2002/11/19 12:36:16  tipaul
3177 # road to 1.3.2
3178 # various bugfixes, improvments, and migration from acquisition.pm to biblio.pm
3179 #
3180 # Revision 1.26  2002/11/12 15:58:43  tipaul
3181 # road to 1.3.2 :
3182 # * many bugfixes
3183 # * adding value_builder : you can map a subfield in the marc_subfield_structure to a sub stored in "value_builder" directory. In this directory you can create screen used to build values with any method. In this commit is a 1st draft of the builder for 100$a unimarc french subfield, which is composed of 35 digits, with 12 differents values (only the 4th first are provided for instance)
3184 #
3185 # Revision 1.25  2002/10/25 10:58:26  tipaul
3186 # Road to 1.3.2
3187 # * bugfixes and improvements
3188 #
3189 # Revision 1.24  2002/10/24 12:09:01  arensb
3190 # Fixed "no title" warning when generating HTML documentation from POD.
3191 #
3192 # Revision 1.23  2002/10/16 12:43:08  arensb
3193 # Added some FIXME comments.
3194 #
3195 # Revision 1.22  2002/10/15 13:39:17  tipaul
3196 # removing Acquisition.pm
3197 # deleting unused code in biblio.pm, rewriting POD and answering most FIXME comments
3198 #
3199 # Revision 1.21  2002/10/13 11:34:14  arensb
3200 # Replaced expressions of the form "$x = $x <op> $y" with "$x <op>= $y".
3201 # Thus, $x = $x+2 becomes $x += 2, and so forth.
3202 #
3203 # Revision 1.20  2002/10/13 08:28:32  arensb
3204 # Deleted unused variables.
3205 # Removed trailing whitespace.
3206 #
3207 # Revision 1.19  2002/10/13 05:56:10  arensb
3208 # Added some FIXME comments.
3209 #
3210 # Revision 1.18  2002/10/11 12:34:53  arensb
3211 # Replaced &requireDBI with C4::Context->dbh
3212 #
3213 # Revision 1.17  2002/10/10 14:48:25  tipaul
3214 # bugfixes
3215 #
3216 # Revision 1.16  2002/10/07 14:04:26  tipaul
3217 # road to 1.3.1 : viewing MARC biblio
3218 #
3219 # Revision 1.15  2002/10/05 09:49:25  arensb
3220 # Merged with arensb-context branch: use C4::Context->dbh instead of
3221 # &C4Connect, and generally prefer C4::Context over C4::Database.
3222 #
3223 # Revision 1.14  2002/10/03 11:28:18  tipaul
3224 # Extending Context.pm to add stopword management and using it in MARC-API.
3225 # First benchmarks show a medium speed improvement, which  is nice as this part is heavily called.
3226 #
3227 # Revision 1.13  2002/10/02 16:26:44  tipaul
3228 # road to 1.3.1
3229 #
3230 # Revision 1.12.2.4  2002/10/05 07:09:31  arensb
3231 # Merged in changes from main branch.
3232 #
3233 # Revision 1.12.2.3  2002/10/05 06:12:10  arensb
3234 # Added a whole mess of FIXME comments.
3235 #
3236 # Revision 1.12.2.2  2002/10/05 04:03:14  arensb
3237 # Added some missing semicolons.
3238 #
3239 # Revision 1.12.2.1  2002/10/04 02:24:01  arensb
3240 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3241 # C4Connect.
3242 #
3243 # Revision 1.12.2.3  2002/10/05 06:12:10  arensb
3244 # Added a whole mess of FIXME comments.
3245 #
3246 # Revision 1.12.2.2  2002/10/05 04:03:14  arensb
3247 # Added some missing semicolons.
3248 #
3249 # Revision 1.12.2.1  2002/10/04 02:24:01  arensb
3250 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3251 # C4Connect.
3252 #
3253 # Revision 1.12  2002/10/01 11:48:51  arensb
3254 # Added some FIXME comments, mostly marking duplicate functions.
3255 #
3256 # Revision 1.11  2002/09/24 13:49:26  tipaul
3257 # long WAS the road to 1.3.0...
3258 # coming VERY SOON NOW...
3259 # modifying installer and buildrelease to update the DB
3260 #
3261 # Revision 1.10  2002/09/22 16:50:08  arensb
3262 # Added some FIXME comments.
3263 #
3264 # Revision 1.9  2002/09/20 12:57:46  tipaul
3265 # long is the road to 1.4.0
3266 # * MARCadditem and MARCmoditem now wroks
3267 # * various bugfixes in MARC management
3268 # !!! 1.3.0 should be released very soon now. Be careful !!!
3269 #
3270 # Revision 1.8  2002/09/10 13:53:52  tipaul
3271 # MARC API continued...
3272 # * some bugfixes
3273 # * multiple item management : MARCadditem and MARCmoditem have been added. They suppose that ALL the MARC field linked to koha-item are in the same MARC tag (on the same line of MARC file)
3274 #
3275 # Note : it should not be hard for marcimport and marcexport to re-link fields from internal tag/subfield to "legal" tag/subfield.
3276 #
3277 # Revision 1.7  2002/08/14 18:12:51  tonnesen
3278 # Added copyright statement to all .pl and .pm files
3279 #
3280 # Revision 1.6  2002/07/25 13:40:31  tipaul
3281 # pod documenting the API.
3282 #
3283 # Revision 1.5  2002/07/24 16:11:37  tipaul
3284 # Now, the API...
3285 # Database.pm and Output.pm are almost not modified (var test...)
3286 #
3287 # Biblio.pm is almost completly rewritten.
3288 #
3289 # WHAT DOES IT ??? ==> END of Hitchcock suspens
3290 #
3291 # 1st, it does... nothing...
3292 # Every old API should be there. So if MARC-stuff is not done, the behaviour is EXACTLY the same (if there is no added bug, of course). So, if you use normal acquisition, you won't find anything new neither on screen or old-DB tables ...
3293 #
3294 # All old-API functions have been cloned. for example, the "newbiblio" sub, now has become :
3295 # * a "newbiblio" sub, with the same parameters. It just call a sub named OLDnewbiblio
3296 # * a "OLDnewbiblio" sub, which is a copy/paste of the previous newbiblio sub. Then, when you want to add the MARC-DB stuff, you can modify the newbiblio sub without modifying the OLDnewbiblio one. If we correct a bug in 1.2 in newbiblio, we can do the same in main branch by correcting OLDnewbiblio.
3297 # * The MARC stuff is usually done through a sub named MARCxxx where xxx is the same as OLDxxx. For example, newbiblio calls MARCnewbiblio. the MARCxxx subs use a MARC::Record as parameter.
3298 # The last thing to solve was to manage biblios through real MARC import : they must populate the old-db, but must populate the MARC-DB too, without loosing information (if we go from MARC::Record to old-data then back to MARC::Record, we loose A LOT OF ROWS). To do this, there are subs beginning by "NEWxxx" : they manage datas with MARC::Record datas. they call OLDxxx sub too (to populate old-DB), but MARCxxx subs too, with a complete MARC::Record ;-)
3299 #
3300 # In Biblio.pm, there are some subs that permits to build a old-style record from a MARC::Record, and the opposite. There is also a sub finding a MARC-bibid from a old-biblionumber and the opposite too.
3301 # Note we have decided with steve that a old-biblio <=> a MARC-Biblio.
3302 #