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