re-input an old function.
[koha-ffzg.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 $query;
1719 ##Recalculate LC in case it changed --TG
1720
1721     $biblioitem->{'itemtype'}      = $dbh->quote( $biblioitem->{'itemtype'} );
1722     $biblioitem->{'url'}           = $dbh->quote( $biblioitem->{'url'} );
1723     $biblioitem->{'isbn'}          = $dbh->quote( $biblioitem->{'isbn'} );
1724     $biblioitem->{'issn'}          = $dbh->quote( $biblioitem->{'issn'} );
1725     $biblioitem->{'publishercode'} =
1726       $dbh->quote( $biblioitem->{'publishercode'} );
1727     $biblioitem->{'publicationyear'} =
1728       $dbh->quote( $biblioitem->{'publicationyear'} );
1729     $biblioitem->{'classification'} =      $dbh->quote( $biblioitem->{'classification'} );
1730     $biblioitem->{'dewey'}       = $dbh->quote( $biblioitem->{'dewey'} );
1731     $biblioitem->{'subclass'}    = $dbh->quote( $biblioitem->{'subclass'} );
1732     $biblioitem->{'illus'}       = $dbh->quote( $biblioitem->{'illus'} );
1733     $biblioitem->{'pages'}       = $dbh->quote( $biblioitem->{'pages'} );
1734     $biblioitem->{'volumeddesc'} = $dbh->quote( $biblioitem->{'volumeddesc'} );
1735     $biblioitem->{'bnotes'}      = $dbh->quote( $biblioitem->{'bnotes'} );
1736     $biblioitem->{'size'}        = $dbh->quote( $biblioitem->{'size'} );
1737     $biblioitem->{'place'}       = $dbh->quote( $biblioitem->{'place'} );
1738 my($lcsort)=calculatelc($biblioitem->{'classification'}).$biblioitem->{'subclass'};
1739
1740
1741 $lcsort=$dbh->quote($lcsort);
1742
1743
1744  $query = "Update biblioitems set
1745 itemtype        = $biblioitem->{'itemtype'},
1746 url             = $biblioitem->{'url'},
1747 isbn            = $biblioitem->{'isbn'},
1748 issn            = $biblioitem->{'issn'},
1749 publishercode   = $biblioitem->{'publishercode'},
1750 publicationyear = $biblioitem->{'publicationyear'},
1751 classification  = $biblioitem->{'classification'},
1752 dewey           = $biblioitem->{'dewey'},
1753 subclass        = $biblioitem->{'subclass'},
1754 illus           = $biblioitem->{'illus'},
1755 pages           = $biblioitem->{'pages'},
1756 volumeddesc     = $biblioitem->{'volumeddesc'},
1757 notes           = $biblioitem->{'bnotes'},
1758 size            = $biblioitem->{'size'},
1759 place           = $biblioitem->{'place'},
1760 lcsort  =$lcsort where biblionumber = $biblioitem->{'biblionumber'}";
1761
1762     $dbh->do($query);
1763     if ( $dbh->errstr ) {
1764                 warn "$query";
1765     }
1766 }    # sub modbibitem
1767
1768 sub OLDmodnote {
1769     my ( $dbh, $bibitemnum, $note ) = @_;
1770
1771     #  my $dbh=C4Connect;
1772     my $query = "update biblioitems set notes='$note' where
1773   biblioitemnumber='$bibitemnum'";
1774     my $sth = $dbh->prepare($query);
1775     $sth->execute;
1776     $sth->finish;
1777
1778     #  $dbh->disconnect;
1779 }
1780
1781 sub OLDnewbiblioitem {
1782     my ( $dbh, $biblioitem ) = @_;
1783
1784     #  my $dbh   = C4Connect;
1785     my $sth = $dbh->prepare("Select max(biblioitemnumber) from biblioitems");
1786     my $data;
1787     my $bibitemnum;
1788
1789     $sth->execute;
1790     $data       = $sth->fetchrow_arrayref;
1791     $bibitemnum = $$data[0] + 1;
1792
1793     $sth->finish;
1794
1795     $sth = $dbh->prepare( "insert into biblioitems set
1796                                                                         biblioitemnumber = ?,           biblionumber     = ?,
1797                                                                         volume           = ?,                   number           = ?,
1798                                                                         classification  = ?,                    itemtype         = ?,
1799                                                                         url              = ?,                           isbn             = ?,
1800                                                                         issn             = ?,                           dewey            = ?,
1801                                                                         subclass         = ?,                           publicationyear  = ?,
1802                                                                         publishercode    = ?,           volumedate       = ?,
1803                                                                         volumeddesc      = ?,           illus            = ?,
1804                                                                         pages            = ?,                           notes            = ?,
1805                                                                         size             = ?,                           lccn             = ?,
1806                                                                         marc             = ?,   
1807                                                                                         
1808                                                                         place            = ?, lcsort=?
1809                                                                         "
1810     );
1811 my ($lcsort)=calculatelc($biblioitem->{'classification'}).$biblioitem->{'subclass'};
1812     $sth->execute(
1813         $bibitemnum,                     $biblioitem->{'biblionumber'},
1814         $biblioitem->{'volume'},         $biblioitem->{'number'},
1815         $biblioitem->{'classification'}, $biblioitem->{'itemtype'},
1816         $biblioitem->{'url'},            $biblioitem->{'isbn'},
1817         $biblioitem->{'issn'},           $biblioitem->{'dewey'},
1818         $biblioitem->{'subclass'},       $biblioitem->{'publicationyear'},
1819         $biblioitem->{'publishercode'},  $biblioitem->{'volumedate'},
1820         $biblioitem->{'volumeddesc'},    $biblioitem->{'illus'},
1821         $biblioitem->{'pages'},          $biblioitem->{'bnotes'},
1822         $biblioitem->{'size'},           $biblioitem->{'lccn'},
1823         $biblioitem->{'marc'},           $biblioitem->{'place'},$lcsort
1824     );
1825     $sth->finish;
1826
1827     #    $dbh->disconnect;
1828     return ($bibitemnum);
1829 }
1830
1831 sub OLDnewsubject {
1832     my ( $dbh, $bibnum ) = @_;
1833     my $sth =
1834       $dbh->prepare("insert into bibliosubject (biblionumber) values (?)");
1835     $sth->execute($bibnum);
1836     $sth->finish;
1837 }
1838
1839 sub OLDnewsubtitle {
1840     my ( $dbh, $bibnum, $subtitle ) = @_;
1841     my $sth =
1842       $dbh->prepare(
1843         "insert into bibliosubtitle set biblionumber = ?, subtitle = ?");
1844     $sth->execute( $bibnum, $subtitle ) if $subtitle;
1845     $sth->finish;
1846 }
1847
1848 sub OLDnewitems {
1849     my ( $dbh, $item, $barcode ) = @_;
1850
1851     #  my $dbh   = C4Connect;
1852     my $sth = $dbh->prepare("Select max(itemnumber) from items");
1853     my $data;
1854     my $itemnumber;
1855     my $error = "";
1856
1857     $sth->execute;
1858     $data       = $sth->fetchrow_hashref;
1859     $itemnumber = $data->{'max(itemnumber)'} + 1;
1860     $sth->finish;
1861     $sth->finish;
1862 ## Now calculate lccalnumber
1863 my ($cutterextra)=itemcalculator($dbh,$item->{'biblioitemnumber'},$item->{'itemcallnumber'});
1864 # FIXME the "notforloan" field seems to be named "loan" in some places. workaround bugfix.
1865     if ( $item->{'loan'} ) {
1866         $item->{'notforloan'} = $item->{'loan'};
1867     }
1868
1869     # if dateaccessioned is provided, use it. Otherwise, set to NOW()
1870     if ( $item->{'dateaccessioned'} eq '' || !$item->{'dateaccessioned'} ) {
1871
1872         $sth = $dbh->prepare( "Insert into items set
1873                                                         itemnumber           = ?,                       biblionumber         = ?,
1874                                                         multivolumepart      = ?,
1875                                                         biblioitemnumber     = ?,                       barcode              = ?,
1876                                                         booksellerid         = ?,                       dateaccessioned      = NOW(),
1877                                                         homebranch           = ?,                       holdingbranch        = ?,
1878                                                         price                = ?,                       replacementprice     = ?,
1879                                                         replacementpricedate = NOW(),           datelastseen            = NOW(),
1880                                                         multivolume                     = ?,                    stack                           = ?,
1881                                                         itemlost                        = ?,                    wthdrawn                        = ?,
1882                                                         paidfor                         = ?,                    itemnotes            = ?,
1883                                                         itemcallnumber  =?,                                                     notforloan = ?,
1884                                                         location = ?,
1885                                                         Cutterextra=?
1886                                                         "
1887         );
1888         $sth->execute(
1889                         $itemnumber,                            $item->{'biblionumber'},
1890                         $item->{'multivolumepart'},
1891                         $item->{'biblioitemnumber'},$barcode,
1892                         $item->{'booksellerid'},        
1893                         $item->{'homebranch'},          $item->{'holdingbranch'},
1894                         $item->{'price'},                       $item->{'replacementprice'},
1895                         $item->{multivolume},           $item->{stack},
1896                         $item->{itemlost},                      $item->{wthdrawn},
1897                         $item->{paidfor},                       $item->{'itemnotes'},
1898                         $item->{'itemcallnumber'},      $item->{'notforloan'},
1899                         $item->{'location'},$cutterextra
1900         );
1901     }
1902     else {
1903         $sth = $dbh->prepare( "Insert into items set
1904                                                         itemnumber           = ?,                       biblionumber         = ?,
1905                                                         multivolumepart      = ?,
1906                                                         biblioitemnumber     = ?,                       barcode              = ?,
1907                                                         booksellerid         = ?,                       dateaccessioned      = ?,
1908                                                         homebranch           = ?,                       holdingbranch        = ?,
1909                                                         price                = ?,                       replacementprice     = ?,
1910                                                         replacementpricedate = NOW(),           datelastseen            = NOW(),
1911                                                         multivolume                     = ?,                    stack                           = ?,
1912                                                         itemlost                        = ?,                    wthdrawn                        = ?,
1913                                                         paidfor                         = ?,                    itemnotes            = ?,
1914                                                         itemcallnumber  =?,                                                     notforloan = ?,
1915                                                         location = ?,
1916                                                         Cutterextra=?
1917                                                         "
1918         );
1919         $sth->execute(
1920                         $itemnumber,                            $item->{'biblionumber'},
1921                         $item->{'multivolumepart'},
1922                         $item->{'biblioitemnumber'},$barcode,
1923                         $item->{'booksellerid'},        $item->{'dateaccessioned'},
1924                         $item->{'homebranch'},          $item->{'holdingbranch'},
1925                         $item->{'price'},                       $item->{'replacementprice'},
1926                         $item->{multivolume},           $item->{stack},
1927                         $item->{itemlost},                      $item->{wthdrawn},
1928                         $item->{paidfor},                       $item->{'itemnotes'},
1929                         $item->{'itemcallnumber'},      $item->{'notforloan'},
1930                         $item->{'location'},$cutterextra
1931         );
1932     }
1933     if ( defined $sth->errstr ) {
1934         $error .= $sth->errstr;
1935     }
1936
1937     return ( $itemnumber, $error );
1938 }
1939
1940 sub OLDmoditem {
1941     my ( $dbh, $item ) = @_;
1942     $item->{'itemnum'} = $item->{'itemnumber'} unless $item->{'itemnum'};
1943
1944 ## Now calculate lccalnumber
1945 my ($cutterextra)=itemcalculator($dbh,$item->{'bibitemnum'},$item->{'itemcallnumber'});
1946     my $query = "update items set  barcode=?,itemnotes=?,itemcallnumber=?,notforloan=?,location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?,holdingbranch=?,homebranch=?,cutterextra=?, onloan=?";
1947     my @bind = (
1948         $item->{'barcode'},                     $item->{'notes'},
1949         $item->{'itemcallnumber'},      $item->{'notforloan'},
1950         $item->{'location'},            $item->{multivolumepart},
1951                 $item->{multivolume},           $item->{stack},
1952                 $item->{wthdrawn},$item->{holdingbranch},$item->{homebranch},$cutterextra,$item->{onloan}
1953     );
1954     if ( $item->{'lost'} ne '' ) {
1955         $query = "update items set biblioitemnumber=?,barcode=?,itemnotes=?,homebranch=?,
1956                                                         itemlost=?,wthdrawn=?,itemcallnumber=?,notforloan=?,
1957                                                         location=?,multivolumepart=?,multivolume=?,stack=?,wthdrawn=?,holdingbranch=?,cutterextra=?,onloan=?";
1958         @bind = (
1959             $item->{'bibitemnum'},     $item->{'barcode'},
1960             $item->{'notes'},          $item->{'homebranch'},
1961             $item->{'lost'},           $item->{'wthdrawn'},
1962             $item->{'itemcallnumber'}, $item->{'notforloan'},
1963             $item->{'location'},                $item->{multivolumepart},
1964                         $item->{multivolume},           $item->{stack},
1965                         $item->{wthdrawn},$item->{holdingbranch},$cutterextra,$item->{onloan}
1966         );
1967 #               if ($item->{homebranch}) {
1968 #                       $query.=",homebranch=?";
1969 #                       push @bind, $item->{homebranch};
1970 #               }
1971 #               if ($item->{holdingbranch}) {
1972 #                       $query.=",holdingbranch=?";
1973 #                       push @bind, $item->{holdingbranch};
1974 #               }
1975     }
1976         $query.=" where itemnumber=?";
1977         push @bind,$item->{'itemnum'};
1978    if ( $item->{'replacement'} ne '' ) {
1979         $query =~ s/ where/,replacementprice='$item->{'replacement'}' where/;
1980     }
1981     my $sth = $dbh->prepare($query);
1982     $sth->execute(@bind);
1983     $sth->finish;
1984
1985     #  $dbh->disconnect;
1986 }
1987
1988 sub OLDdelitem {
1989     my ( $dbh, $itemnum ) = @_;
1990
1991     #  my $dbh=C4Connect;
1992     my $sth = $dbh->prepare("select * from items where itemnumber=?");
1993     $sth->execute($itemnum);
1994     my $data = $sth->fetchrow_hashref;
1995     $sth->finish;
1996     my $query = "Insert into deleteditems set ";
1997     my @bind  = ();
1998     foreach my $temp ( keys %$data ) {
1999         $query .= "$temp = ?,";
2000         push ( @bind, $data->{$temp} );
2001     }
2002     $query =~ s/\,$//;
2003
2004     #  print $query;
2005     $sth = $dbh->prepare($query);
2006 #    $sth->execute(@bind);
2007 #    $sth->finish;
2008     $sth = $dbh->prepare("Delete from items where itemnumber=?");
2009     $sth->execute($itemnum);
2010     $sth->finish;
2011
2012     #  $dbh->disconnect;
2013 }
2014
2015 sub OLDdeletebiblioitem {
2016     my ( $dbh, $biblioitemnumber ) = @_;
2017
2018     #    my $dbh   = C4Connect;
2019     my $sth = $dbh->prepare( "Select * from biblioitems
2020 where biblioitemnumber = ?"
2021     );
2022     my $results;
2023
2024     $sth->execute($biblioitemnumber);
2025
2026     if ( $results = $sth->fetchrow_hashref ) {
2027         $sth->finish;
2028         $sth =
2029           $dbh->prepare(
2030 "Insert into deletedbiblioitems (biblioitemnumber, biblionumber, volume, number, classification, itemtype,
2031                                         isbn, issn ,dewey ,subclass ,publicationyear ,publishercode ,volumedate ,volumeddesc ,timestamp ,illus ,
2032                                         pages ,notes ,size ,url ,lccn ) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
2033         );
2034
2035         $sth->execute(
2036             $results->{biblioitemnumber}, $results->{biblionumber},
2037             $results->{volume},           $results->{number},
2038             $results->{classification},   $results->{itemtype},
2039             $results->{isbn},             $results->{issn},
2040             $results->{dewey},            $results->{subclass},
2041             $results->{publicationyear},  $results->{publishercode},
2042             $results->{volumedate},       $results->{volumeddesc},
2043             $results->{timestamp},        $results->{illus},
2044             $results->{pages},            $results->{notes},
2045             $results->{size},             $results->{url},
2046             $results->{lccn}
2047         );
2048         my $sth2 =
2049           $dbh->prepare("Delete from biblioitems where biblioitemnumber = ?");
2050         $sth2->execute($biblioitemnumber);
2051         $sth2->finish();
2052     }    # if
2053     $sth->finish;
2054
2055     # Now delete all the items attached to the biblioitem
2056     $sth = $dbh->prepare("Select * from items where biblioitemnumber = ?");
2057     $sth->execute($biblioitemnumber);
2058     my @results;
2059 #    while ( my $data = $sth->fetchrow_hashref ) {
2060 #        my $query = "Insert into deleteditems set ";
2061 #        my @bind  = ();
2062 #        foreach my $temp ( keys %$data ) {
2063 #            $query .= "$temp = ?,";
2064 #           push ( @bind, $data->{$temp} );
2065 #        }
2066 #        $query =~ s/\,$//;
2067 #        my $sth2 = $dbh->prepare($query);
2068 #        $sth2->execute(@bind);
2069 #    }    # while
2070     $sth->finish;
2071     $sth = $dbh->prepare("Delete from items where biblioitemnumber = ?");
2072     $sth->execute($biblioitemnumber);
2073     $sth->finish();
2074
2075     #    $dbh->disconnect;
2076 }    # sub deletebiblioitem
2077
2078 sub OLDdelbiblio {
2079     my ( $dbh, $biblio ) = @_;
2080     my $sth = $dbh->prepare("select * from biblio where biblionumber=?");
2081     $sth->execute($biblio);
2082     if ( my $data = $sth->fetchrow_hashref ) {
2083         $sth->finish;
2084         my $query = "Insert into deletedbiblio set ";
2085         my @bind  = ();
2086         foreach my $temp ( keys %$data ) {
2087             $query .= "$temp = ?,";
2088             push ( @bind, $data->{$temp} );
2089         }
2090
2091         #replacing the last , by ",?)"
2092         $query =~ s/\,$//;
2093         $sth = $dbh->prepare($query);
2094         $sth->execute(@bind);
2095         $sth->finish;
2096         $sth = $dbh->prepare("Delete from biblio where biblionumber=?");
2097         $sth->execute($biblio);
2098         $sth->finish;
2099     }
2100     $sth->finish;
2101 }
2102
2103 #
2104 #
2105 # old functions
2106 #
2107 #
2108
2109 sub itemcount {
2110     my ($biblio) = @_;
2111     my $dbh = C4::Context->dbh;
2112
2113     #  print $query;
2114     my $sth = $dbh->prepare("Select count(*) from items where biblionumber=?");
2115     $sth->execute($biblio);
2116     my $data = $sth->fetchrow_hashref;
2117     $sth->finish;
2118     return ( $data->{'count(*)'} );
2119 }
2120
2121 sub newbiblio {
2122     my ($biblio) = @_;
2123     my $dbh    = C4::Context->dbh;
2124     my $bibnum = OLDnewbiblio( $dbh, $biblio );
2125     # finds new (MARC bibid
2126     #   my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
2127     my $record = &MARCkoha2marcBiblio( $dbh, $bibnum );
2128     MARCaddbiblio($record, $bibnum,'' );
2129     return ($bibnum);
2130 }
2131
2132 =item modbiblio
2133
2134   $biblionumber = &modbiblio($biblio);
2135
2136 Update a biblio record.
2137
2138 C<$biblio> is a reference-to-hash whose keys are the fields in the
2139 biblio table in the Koha database. All fields must be present, not
2140 just the ones you wish to change.
2141
2142 C<&modbiblio> updates the record defined by
2143 C<$biblio-E<gt>{biblionumber}> with the values in C<$biblio>.
2144
2145 C<&modbiblio> returns C<$biblio-E<gt>{biblionumber}> whether it was
2146 successful or not.
2147
2148 =cut
2149
2150 sub modbiblio {
2151         my ($biblio) = @_;
2152         my $dbh  = C4::Context->dbh;
2153         my $biblionumber=OLDmodbiblio($dbh,$biblio);
2154         my $record = MARCkoha2marcBiblio($dbh,$biblionumber,$biblionumber);
2155         # finds new (MARC bibid
2156         my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$biblionumber);
2157         MARCmodbiblio($bibid,$record,"",0);
2158         return($biblionumber);
2159 } # sub modbiblio
2160
2161 =item modsubtitle
2162
2163   &modsubtitle($biblionumber, $subtitle);
2164
2165 Sets the subtitle of a book.
2166
2167 C<$biblionumber> is the biblionumber of the book to modify.
2168
2169 C<$subtitle> is the new subtitle.
2170
2171 =cut
2172
2173 sub modsubtitle {
2174     my ( $bibnum, $subtitle ) = @_;
2175     my $dbh = C4::Context->dbh;
2176     &OLDmodsubtitle( $dbh, $bibnum, $subtitle );
2177 }    # sub modsubtitle
2178
2179 =item modaddauthor
2180
2181   &modaddauthor($biblionumber, $author);
2182
2183 Replaces all additional authors for the book with biblio number
2184 C<$biblionumber> with C<$author>. If C<$author> is the empty string,
2185 C<&modaddauthor> deletes all additional authors.
2186
2187 =cut
2188
2189 sub modaddauthor {
2190     my ( $bibnum, @authors ) = @_;
2191     my $dbh = C4::Context->dbh;
2192     &OLDmodaddauthor( $dbh, $bibnum, @authors );
2193 }    # sub modaddauthor
2194
2195 =item modsubject
2196
2197   $error = &modsubject($biblionumber, $force, @subjects);
2198
2199 $force - a subject to force
2200
2201 $error - Error message, or undef if successful.
2202
2203 =cut
2204
2205 sub modsubject {
2206     my ( $bibnum, $force, @subject ) = @_;
2207     my $dbh = C4::Context->dbh;
2208     my $error = &OLDmodsubject( $dbh, $bibnum, $force, @subject );
2209     if ($error eq ''){
2210                 # When MARC is off, ensures that the MARC biblio table gets updated with new
2211                 # subjects, of course, it deletes the biblio in marc, and then recreates.
2212                 # This check is to ensure that no MARC data exists to lose.
2213                 if (C4::Context->preference("MARC") eq '0'){
2214                         my $MARCRecord = &MARCkoha2marcBiblio($dbh,$bibnum);
2215                         my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber($dbh,$bibnum);
2216                         &MARCmodbiblio($bibid, $MARCRecord);
2217                 }
2218         }
2219         return ($error);
2220 }    # sub modsubject
2221
2222 sub modbibitem {
2223     my ($biblioitem) = @_;
2224     my $dbh = C4::Context->dbh;
2225     &OLDmodbibitem( $dbh, $biblioitem );
2226 }    # sub modbibitem
2227
2228 sub modnote {
2229     my ( $bibitemnum, $note ) = @_;
2230     my $dbh = C4::Context->dbh;
2231     &OLDmodnote( $dbh, $bibitemnum, $note );
2232 }
2233
2234 sub newbiblioitem {
2235     my ($biblioitem) = @_;
2236     my $dbh        = C4::Context->dbh;
2237     my $bibitemnum = &OLDnewbiblioitem( $dbh, $biblioitem );
2238     my $MARCbiblio =
2239       MARCkoha2marcBiblio( $dbh, 0, $bibitemnum )
2240       ; # the 0 means "do NOT retrieve biblio, only biblioitem, in the MARC record
2241     &MARCaddbiblio($MARCbiblio, $biblioitem->{biblionumber}, '' );
2242     return ($bibitemnum);
2243 }
2244
2245 sub newsubject {
2246     my ($bibnum) = @_;
2247     my $dbh = C4::Context->dbh;
2248     &OLDnewsubject( $dbh, $bibnum );
2249 }
2250
2251 sub newsubtitle {
2252     my ( $bibnum, $subtitle ) = @_;
2253     my $dbh = C4::Context->dbh;
2254     &OLDnewsubtitle( $dbh, $bibnum, $subtitle );
2255 }
2256
2257 sub newitems {
2258     my ( $item, @barcodes ) = @_;
2259     my $dbh = C4::Context->dbh;
2260     my $errors;
2261     my $itemnumber;
2262     my $error;
2263     foreach my $barcode (@barcodes) {
2264         ( $itemnumber, $error ) = &OLDnewitems( $dbh, $item, uc($barcode) );
2265         $errors .= $error;
2266         my $MARCitem =
2267           &MARCkoha2marcItem( $dbh, $item->{biblionumber}, $itemnumber );
2268         &MARCadditem( $dbh, $MARCitem, $item->{biblionumber} );
2269     }
2270     return ($errors);
2271 }
2272
2273 sub moditem {
2274     my ($item) = @_;
2275     my $dbh = C4::Context->dbh;
2276     &OLDmoditem( $dbh, $item );
2277     my $MARCitem =
2278       &MARCkoha2marcItem( $dbh, $item->{'biblionumber'}, $item->{'itemnum'} );
2279     my $bibid =
2280       &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $item->{biblionumber} );
2281     &MARCmoditem( $dbh, $MARCitem, $bibid, $item->{itemnum}, 0 );
2282 }
2283
2284 sub checkitems {
2285     my ( $count, @barcodes ) = @_;
2286     my $dbh = C4::Context->dbh;
2287     my $error;
2288     my $sth = $dbh->prepare("Select * from items where barcode=?");
2289     for ( my $i = 0 ; $i < $count ; $i++ ) {
2290         $barcodes[$i] = uc $barcodes[$i];
2291         $sth->execute( $barcodes[$i] );
2292         if ( my $data = $sth->fetchrow_hashref ) {
2293             $error .= " Duplicate Barcode: $barcodes[$i]";
2294         }
2295     }
2296     $sth->finish;
2297     return ($error);
2298 }
2299
2300 sub countitems {
2301     my ($bibitemnum) = @_;
2302     my $dbh   = C4::Context->dbh;
2303     my $query = "";
2304     my $sth   =
2305       $dbh->prepare("Select count(*) from items where biblioitemnumber=?");
2306     $sth->execute($bibitemnum);
2307     my $data = $sth->fetchrow_hashref;
2308     $sth->finish;
2309     return ( $data->{'count(*)'} );
2310 }
2311
2312 sub delitem {
2313     my ($itemnum) = @_;
2314     my $dbh = C4::Context->dbh;
2315     &OLDdelitem( $dbh, $itemnum );
2316 }
2317
2318 sub deletebiblioitem {
2319     my ($biblioitemnumber) = @_;
2320     my $dbh = C4::Context->dbh;
2321     &OLDdeletebiblioitem( $dbh, $biblioitemnumber );
2322 }    # sub deletebiblioitem
2323
2324 sub delbiblio {
2325     my ($biblio) = @_;
2326     my $dbh = C4::Context->dbh;
2327     &OLDdelbiblio( $dbh, $biblio );
2328     my $bibid = &MARCfind_MARCbibid_from_oldbiblionumber( $dbh, $biblio );
2329     &MARCdelbiblio( $dbh, $bibid, 0 );
2330 }
2331
2332 =item GetBiblioItemByBiblioNumber
2333
2334 NOTE : This function has been copy/paste from C4/Biblio.pm from head before zebra integration.
2335
2336 =cut
2337
2338 sub GetBiblioItemByBiblioNumber {
2339     my ($biblionumber) = @_;
2340     my $dbh = C4::Context->dbh;
2341     my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2342     my $count = 0;
2343     my @results;
2344
2345     $sth->execute($biblionumber);
2346
2347     while ( my $data = $sth->fetchrow_hashref ) {
2348         push @results, $data;
2349     }
2350
2351     $sth->finish;
2352     return @results;
2353 }    # sub
2354
2355 sub getbiblio {
2356     my ($biblionumber) = @_;
2357     my $dbh = C4::Context->dbh;
2358     my $sth = $dbh->prepare("Select * from biblio where biblionumber = ?");
2359
2360     # || die "Cannot prepare $query\n" . $dbh->errstr;
2361     my $count = 0;
2362     my @results;
2363
2364     $sth->execute($biblionumber);
2365
2366     # || die "Cannot execute $query\n" . $sth->errstr;
2367     while ( my $data = $sth->fetchrow_hashref ) {
2368         $results[$count] = $data;
2369         $count++;
2370     }    # while
2371
2372     $sth->finish;
2373     return ( $count, @results );
2374 }    # sub getbiblio
2375
2376 sub getbiblioitem {
2377     my ($biblioitemnum) = @_;
2378     my $dbh = C4::Context->dbh;
2379     my $sth = $dbh->prepare( "Select * from biblioitems where
2380 biblioitemnumber = ?"
2381     );
2382     my $count = 0;
2383     my @results;
2384
2385     $sth->execute($biblioitemnum);
2386
2387     while ( my $data = $sth->fetchrow_hashref ) {
2388         $results[$count] = $data;
2389         $count++;
2390     }    # while
2391
2392     $sth->finish;
2393     return ( $count, @results );
2394 }    # sub getbiblioitem
2395
2396 sub getbiblioitembybiblionumber {
2397     my ($biblionumber) = @_;
2398     my $dbh = C4::Context->dbh;
2399     my $sth = $dbh->prepare("Select * from biblioitems where biblionumber = ?");
2400     my $count = 0;
2401     my @results;
2402
2403     $sth->execute($biblionumber);
2404
2405     while ( my $data = $sth->fetchrow_hashref ) {
2406         $results[$count] = $data;
2407         $count++;
2408     }    # while
2409
2410     $sth->finish;
2411     return ( $count, @results );
2412 }    # sub
2413
2414 sub getitemtypes {
2415     my $dbh   = C4::Context->dbh;
2416     my $query = "select * from itemtypes order by description";
2417     my $sth   = $dbh->prepare($query);
2418
2419     # || die "Cannot prepare $query" . $dbh->errstr;      
2420     my $count = 0;
2421     my @results;
2422
2423     $sth->execute;
2424
2425     # || die "Cannot execute $query\n" . $sth->errstr;
2426     while ( my $data = $sth->fetchrow_hashref ) {
2427         $results[$count] = $data;
2428         $count++;
2429     }    # while
2430
2431     $sth->finish;
2432     return ( $count, @results );
2433 }    # sub getitemtypes
2434
2435 sub getstacks{
2436   my $dbh   = C4::Context->dbh;
2437   my $i=0;
2438 my @results;
2439 my $stackstatus = $dbh->prepare('select authorised_value from marc_subfield_structure where kohafield="items.stack"');
2440                 $stackstatus->execute;
2441                 
2442                 my ($authorised_valuecode) = $stackstatus->fetchrow;
2443                 if ($authorised_valuecode) {
2444                         $stackstatus = $dbh->prepare("select * from authorised_values where category=? ");
2445                         $stackstatus->execute($authorised_valuecode);
2446                         
2447                         while (my $data = $stackstatus->fetchrow_hashref){
2448                         $results[$i]=$data;
2449                         $i++;
2450                 }#while
2451                 }#if
2452 $stackstatus->finish;
2453                 return ( $i, @results );
2454
2455 }
2456
2457 sub getitemsbybiblioitem {
2458     my ($biblioitemnum) = @_;
2459     my $dbh = C4::Context->dbh;
2460     my $sth = $dbh->prepare( "Select * from items, biblio where
2461 biblio.biblionumber = items.biblionumber and biblioitemnumber
2462 = ?"
2463     );
2464
2465     # || die "Cannot prepare $query\n" . $dbh->errstr;
2466     my $count = 0;
2467     my @results;
2468
2469     $sth->execute($biblioitemnum);
2470
2471     # || die "Cannot execute $query\n" . $sth->errstr;
2472     while ( my $data = $sth->fetchrow_hashref ) {
2473         $results[$count] = $data;
2474         $count++;
2475     }    # while
2476
2477     $sth->finish;
2478     return ( $count, @results );
2479 }    # sub getitemsbybiblioitem
2480
2481
2482 =head2 get_itemnumbers_of
2483
2484   my @itemnumbers_of = get_itemnumbers_of(@biblionumbers);
2485
2486 Given a list of biblionumbers, return the list of corresponding itemnumbers
2487 for each biblionumber.
2488
2489 Return a reference on a hash where keys are biblionumbers and values are
2490 references on array of itemnumbers.
2491
2492 =cut
2493 sub get_itemnumbers_of {
2494     my @biblionumbers = @_;
2495
2496     my $dbh = C4::Context->dbh;
2497
2498     my $query = '
2499 SELECT itemnumber,
2500        biblionumber
2501   FROM items
2502   WHERE biblionumber IN (?'.(',?' x scalar @biblionumbers - 1).')
2503 ';
2504     my $sth = $dbh->prepare($query);
2505     $sth->execute(@biblionumbers);
2506
2507     my %itemnumbers_of;
2508
2509     while (my ($itemnumber, $biblionumber) = $sth->fetchrow_array) {
2510         push @{$itemnumbers_of{$biblionumber}}, $itemnumber;
2511     }
2512
2513     return \%itemnumbers_of;
2514 }
2515
2516
2517 sub logchange {
2518
2519     # Subroutine to log changes to databases
2520 # Eventually, this subroutine will be used to create a log of all changes made,
2521     # with the possibility of "undo"ing some changes
2522     my $database = shift;
2523     if ( $database eq 'kohadb' ) {
2524         my $type     = shift;
2525         my $section  = shift;
2526         my $item     = shift;
2527         my $original = shift;
2528         my $new      = shift;
2529
2530         #       print STDERR "KOHA: $type $section $item $original $new\n";
2531     }
2532     elsif ( $database eq 'marc' ) {
2533         my $type        = shift;
2534         my $Record_ID   = shift;
2535         my $tag         = shift;
2536         my $mark        = shift;
2537         my $subfield_ID = shift;
2538         my $original    = shift;
2539         my $new         = shift;
2540
2541 #       print STDERR "MARC: $type $Record_ID $tag $mark $subfield_ID $original $new\n";
2542     }
2543 }
2544
2545 #------------------------------------------------
2546
2547 #---------------------------------------
2548 # Find a biblio entry, or create a new one if it doesn't exist.
2549 #  If a "subtitle" entry is in hash, add it to subtitle table
2550 sub getoraddbiblio {
2551
2552     # input params
2553     my (
2554         $dbh,       # db handle
2555                     # FIXME - Unused argument
2556         $biblio,    # hash ref to fields
2557     ) = @_;
2558
2559     # return
2560     my $biblionumber;
2561
2562     my $debug = 0;
2563     my $sth;
2564     my $error;
2565
2566     #-----
2567     $dbh = C4::Context->dbh;
2568
2569     print "<PRE>Looking for biblio </PRE>\n" if $debug;
2570     $sth = $dbh->prepare( "select biblionumber
2571                 from biblio
2572                 where title=? and author=?
2573                   and copyrightdate=? and seriestitle=?"
2574     );
2575     $sth->execute(
2576         $biblio->{title},     $biblio->{author},
2577         $biblio->{copyright}, $biblio->{seriestitle}
2578     );
2579     if ( $sth->rows ) {
2580         ($biblionumber) = $sth->fetchrow;
2581         print "<PRE>Biblio exists with number $biblionumber</PRE>\n" if $debug;
2582     }
2583     else {
2584
2585         # Doesn't exist.  Add new one.
2586         print "<PRE>Adding biblio</PRE>\n" if $debug;
2587         ( $biblionumber, $error ) = &newbiblio($biblio);
2588         if ($biblionumber) {
2589             print "<PRE>Added with biblio number=$biblionumber</PRE>\n"
2590               if $debug;
2591             if ( $biblio->{subtitle} ) {
2592                 &newsubtitle( $biblionumber, $biblio->{subtitle} );
2593             }    # if subtitle
2594         }
2595         else {
2596             print "<PRE>Couldn't add biblio: $error</PRE>\n" if $debug;
2597         }    # if added
2598     }
2599
2600     return $biblionumber, $error;
2601
2602 }    # sub getoraddbiblio
2603
2604 sub char_decode {
2605
2606     # converts ISO 5426 coded string to UTF-8
2607     # sloppy code : should be improved in next issue
2608     my ( $string, $encoding ) = @_;
2609     $_ = $string;
2610
2611         $encoding = C4::Context->preference("marcflavour") unless $encoding;
2612     if ( $encoding eq "UNIMARC" ) {
2613 #         s/\xe1/Æ/gm;
2614         s/\xe2/Ğ/gm;
2615         s/\xe9/Ø/gm;
2616         s/\xec/ş/gm;
2617         s/\xf1/æ/gm;
2618         s/\xf3/ğ/gm;
2619         s/\xf9/ø/gm;
2620         s/\xfb/ß/gm;
2621         s/\xc1\x61/à/gm;
2622         s/\xc1\x65/è/gm;
2623         s/\xc1\x69/ì/gm;
2624         s/\xc1\x6f/ò/gm;
2625         s/\xc1\x75/ù/gm;
2626         s/\xc1\x41/À/gm;
2627         s/\xc1\x45/È/gm;
2628         s/\xc1\x49/Ì/gm;
2629         s/\xc1\x4f/Ò/gm;
2630         s/\xc1\x55/Ù/gm;
2631         s/\xc2\x41/Á/gm;
2632         s/\xc2\x45/É/gm;
2633         s/\xc2\x49/Í/gm;
2634         s/\xc2\x4f/Ó/gm;
2635         s/\xc2\x55/Ú/gm;
2636         s/\xc2\x59/İ/gm;
2637         s/\xc2\x61/á/gm;
2638         s/\xc2\x65/é/gm;
2639         s/\xc2\x69/í/gm;
2640         s/\xc2\x6f/ó/gm;
2641         s/\xc2\x75/ú/gm;
2642         s/\xc2\x79/ı/gm;
2643         s/\xc3\x41/Â/gm;
2644         s/\xc3\x45/Ê/gm;
2645         s/\xc3\x49/Î/gm;
2646         s/\xc3\x4f/Ô/gm;
2647         s/\xc3\x55/Û/gm;
2648         s/\xc3\x61/â/gm;
2649         s/\xc3\x65/ê/gm;
2650         s/\xc3\x69/î/gm;
2651         s/\xc3\x6f/ô/gm;
2652         s/\xc3\x75/û/gm;
2653         s/\xc4\x41/Ã/gm;
2654         s/\xc4\x4e/Ñ/gm;
2655         s/\xc4\x4f/Õ/gm;
2656         s/\xc4\x61/ã/gm;
2657         s/\xc4\x6e/ñ/gm;
2658         s/\xc4\x6f/õ/gm;
2659         s/\xc8\x41/Ä/gm;
2660         s/\xc8\x45/Ë/gm;
2661         s/\xc8\x49/Ï/gm;
2662         s/\xc8\x61/ä/gm;
2663         s/\xc8\x65/ë/gm;
2664         s/\xc8\x69/ï/gm;
2665         s/\xc8\x6F/ö/gm;
2666         s/\xc8\x75/ü/gm;
2667         s/\xc8\x76/ÿ/gm;
2668         s/\xc9\x41/Ä/gm;
2669         s/\xc9\x45/Ë/gm;
2670         s/\xc9\x49/Ï/gm;
2671         s/\xc9\x4f/Ö/gm;
2672         s/\xc9\x55/Ü/gm;
2673         s/\xc9\x61/ä/gm;
2674         s/\xc9\x6f/ö/gm;
2675         s/\xc9\x75/ü/gm;
2676         s/\xca\x41/Å/gm;
2677         s/\xca\x61/å/gm;
2678         s/\xd0\x43/Ç/gm;
2679         s/\xd0\x63/ç/gm;
2680
2681         # this handles non-sorting blocks (if implementation requires this)
2682         $string = nsb_clean($_);
2683     }
2684     elsif ( $encoding eq "USMARC" || $encoding eq "MARC21" ) {
2685  ##MARC-8 to UTF-8    
2686                 
2687             s/\xe1\x61/à/gm;
2688             s/\xe1\x65/è/gm;
2689             s/\xe1\x69/ì/gm;
2690             s/\xe1\x6f/ò/gm;
2691             s/\xe1\x75/ù/gm;
2692             s/\xe1\x41/À/gm;
2693             s/\xe1\x45/È/gm;
2694             s/\xe1\x49/Ì/gm;
2695             s/\xe1\x4f/Ò/gm;
2696             s/\xe1\x55/Ù/gm;
2697             s/\xe2\x41/Á/gm;
2698             s/\xe2\x45/É/gm;
2699             s/\xe2\x49/Í/gm;
2700             s/\xe2\x4f/Ó/gm;
2701             s/\xe2\x55/Ú/gm;
2702             s/\xe2\x59/İ/gm;
2703             s/\xe2\x61/á/gm;
2704             s/\xe2\x65/é/gm;
2705             s/\xe2\x69/í/gm;
2706             s/\xe2\x6f/ó/gm;
2707             s/\xe2\x75/ú/gm;
2708             s/\xe2\x79/ı/gm;
2709             s/\xe3\x41/Â/gm;
2710             s/\xe3\x45/Ê/gm;
2711             s/\xe3\x49/Î/gm;
2712             s/\xe3\x4f/Ô/gm;
2713             s/\xe3\x55/Û/gm;
2714             s/\xe3\x61/â/gm;
2715             s/\xe3\x65/ê/gm;
2716             s/\xe3\x69/î/gm;
2717             s/\xe3\x6f/ô/gm;
2718             s/\xe3\x75/û/gm;
2719             s/\xe4\x41/Ã/gm;
2720             s/\xe4\x4e/Ñ/gm;
2721             s/\xe4\x4f/Õ/gm;
2722             s/\xe4\x61/ã/gm;
2723             s/\xe4\x6e/ñ/gm;
2724             s/\xe4\x6f/õ/gm;
2725             s/\xe6\x41/Ă/gm;
2726             s/\xe6\x45/Ĕ/gm;
2727             s/\xe6\x65/ĕ/gm;
2728             s/\xe6\x61/ă/gm;
2729             s/\xe8\x45/Ë/gm;
2730             s/\xe8\x49/Ï/gm;
2731             s/\xe8\x65/ë/gm;
2732             s/\xe8\x69/ï/gm;
2733             s/\xe8\x76/ÿ/gm;
2734             s/\xe9\x41/A/gm;
2735             s/\xe9\x4f/O/gm;
2736             s/\xe9\x55/U/gm;
2737             s/\xe9\x61/a/gm;
2738             s/\xe9\x6f/o/gm;
2739             s/\xe9\x75/u/gm;
2740             s/\xea\x41/A/gm;
2741             s/\xea\x61/a/gm;
2742 #Additional Turkish characters
2743   s/\x1b//gm;
2744   s/\x1e//gm;
2745  s/(\xf0)s/\xc5\x9f/gm; 
2746          s/(\xf0)S/\xc5\x9e/gm; 
2747                 s/(\xf0)c/ç/gm; 
2748            s/(\xf0)C/Ç/gm;
2749         s/\xe7\x49/\\xc4\xb0/gm;
2750         s/(\xe6)G/\xc4\x9e/gm;
2751         s/(\xe6)g/ğ\xc4\x9f/gm;
2752         s/\xB8/ı/gm;
2753         s/\xB9/£/gm;
2754          s/(\xe8|\xc8)o/ö/gm ;
2755            s/(\xe8|\xc8)O/Ö/gm ;
2756            s/(\xe8|\xc8)u/ü/gm ;
2757            s/(\xe8|\xc8)U/Ü/gm ;
2758         s/\xc2\xb8/\xc4\xb1/gm;
2759         s/¸/\xc4\xb1/gm;
2760             # this handles non-sorting blocks (if implementation requires this)
2761             $string = nsb_clean($_);
2762         
2763     }
2764     return ($string);
2765 }
2766
2767 sub nsb_clean {
2768     my $NSB = '\x88';    # NSB : begin Non Sorting Block
2769     my $NSE = '\x89';    # NSE : Non Sorting Block end
2770                          # handles non sorting blocks
2771     my ($string) = @_;
2772     $_ = $string;
2773     s/$NSB/(/gm;
2774     s/[ ]{0,1}$NSE/) /gm;
2775     $string = $_;
2776     return ($string);
2777 }
2778
2779
2780
2781 sub DisplayISBN {
2782         my ($isbn)=@_;
2783         my $seg1;
2784         if(substr($isbn, 0, 1) <=7) {
2785                 $seg1 = substr($isbn, 0, 1);
2786         } elsif(substr($isbn, 0, 2) <= 94) {
2787                 $seg1 = substr($isbn, 0, 2);
2788         } elsif(substr($isbn, 0, 3) <= 995) {
2789                 $seg1 = substr($isbn, 0, 3);
2790         } elsif(substr($isbn, 0, 4) <= 9989) {
2791                 $seg1 = substr($isbn, 0, 4);
2792         } else {
2793                 $seg1 = substr($isbn, 0, 5);
2794         }
2795         my $x = substr($isbn, length($seg1));
2796         my $seg2;
2797         if(substr($x, 0, 2) <= 19) {
2798 #               if(sTmp2 < 10) sTmp2 = "0" sTmp2;
2799                 $seg2 = substr($x, 0, 2);
2800         } elsif(substr($x, 0, 3) <= 699) {
2801                 $seg2 = substr($x, 0, 3);
2802         } elsif(substr($x, 0, 4) <= 8399) {
2803                 $seg2 = substr($x, 0, 4);
2804         } elsif(substr($x, 0, 5) <= 89999) {
2805                 $seg2 = substr($x, 0, 5);
2806         } elsif(substr($x, 0, 6) <= 9499999) {
2807                 $seg2 = substr($x, 0, 6);
2808         } else {
2809                 $seg2 = substr($x, 0, 7);
2810         }
2811         my $seg3=substr($x,length($seg2));
2812         $seg3=substr($seg3,0,length($seg3)-1) ;
2813         my $seg4 = substr($x, -1, 1);
2814         return "$seg1-$seg2-$seg3-$seg4";
2815 }
2816 sub zebraopfiles{
2817
2818 my ($dbh,$biblionumber,$record,$folder,$server)=@_;
2819 #my $record = XMLgetbiblio($dbh,$biblionumber);
2820 my $op;
2821 my $zebradir = C4::Context->zebraconfig($server)->{directory}."/".$folder."/";
2822         unless (opendir(DIR, "$zebradir")) {
2823                         warn "$zebradir not found";
2824                         return;
2825         } 
2826         closedir DIR;
2827         my $filename = $zebradir.$biblionumber;
2828 if ($record){
2829         open (OUTPUT,">", $filename.".xml");
2830         print OUTPUT $record;
2831
2832         close OUTPUT;
2833 }
2834
2835
2836 }
2837
2838
2839
2840
2841 sub zebraop{
2842 ###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
2843         my ($dbh,$biblionumber,$op,$server) = @_;
2844         my $dbh = C4::Context->dbh;
2845         my @Zconnbiblio;
2846         my $tried=0;
2847         my $recon=0;
2848         my $reconnect=0;
2849         my $record;
2850         my $shadow;
2851 reconnect:
2852         $Zconnbiblio[0]=C4::Context->Zconnauth($server);
2853         if ($server eq "biblioserver"){
2854                 $record =XMLgetbiblio($dbh,$biblionumber);
2855                 warn "******BAR1********";
2856                 $shadow="biblioservershadow";
2857         }elsif($server eq "authorityserver"){
2858                 $record =C4::AuthoritiesMarc::XMLgetauthority($dbh,$biblionumber);
2859                 $shadow="authorityservershadow";
2860         } ## Add other servers as necessary
2861
2862         my $Zpackage = $Zconnbiblio[0]->package();
2863         $Zpackage->option(action => $op);
2864         $Zpackage->option(record => $record);
2865 retry:
2866         $Zpackage->send("update");
2867         my $i;
2868         my $event;
2869
2870         while (($i = ZOOM::event(\@Zconnbiblio)) != 0) {
2871         $event = $Zconnbiblio[0]->last_event();
2872             last if $event == ZOOM::Event::ZEND;
2873         }
2874         my($error, $errmsg, $addinfo, $diagset) = $Zconnbiblio[0]->error_x();
2875         if ($error==10000 && $reconnect==0) { ## This is serious ZEBRA server is not available -reconnect
2876                 $reconnect=1;
2877                 my $res=system('sc start "Z39.50 Server" >c:/zebraserver/error.log');
2878                 warn "Trying to restart ZEBRA Server";
2879                 goto "reconnect";
2880          }elsif ($error==10007 && $tried<2) {## timeout --another 30 looonng seconds for this update
2881                 $tried=$tried+1;
2882                 goto "retry";
2883         }elsif($error==10004 && $recon==0){##Lost connection -reconnect
2884                 $recon=1;
2885                 goto "reconnect";
2886         }elsif ($error){
2887                 warn "Error-$server   $op $biblionumber /errcode:, $error, /MSG:,$errmsg,$addinfo \n";  
2888                 $Zpackage->destroy();
2889                 $Zconnbiblio[0]->destroy();
2890                 zebraopfiles($dbh,$biblionumber,$record,$op,$server);
2891                 return;
2892         }
2893          if (C4::Context->$shadow){
2894                 $Zpackage->send('commit');
2895                 while (($i = ZOOM::event(\@Zconnbiblio)) != 0) {
2896                         #waiting zebra to finish;
2897                 }       
2898         }
2899         $Zpackage->destroy();
2900         $Zconnbiblio[0]->destroy();
2901
2902 }
2903
2904
2905 sub calculatelc{
2906 my  ($classification)=@_;
2907 $classification=~s/^\s+|\s+$//g;
2908 my $i=0;
2909 my $lc2;
2910 my $lc1;
2911
2912
2913 for  ($i=0; $i<length($classification);$i++){
2914 my $c=(substr($classification,$i,1));
2915         if ($c ge '0' && $c le '9'){
2916         
2917         $lc2=substr($classification,$i);
2918         last;
2919         }else{
2920         $lc1.=substr($classification,$i,1);
2921         
2922         }
2923 }#while
2924
2925 my $other=length($lc1);
2926 if(!$lc1){$other==0;}
2927 my $extras;
2928 if ($other<4){
2929         for (1..(4-$other)){
2930         $extras.="0";
2931         }
2932 }
2933  $lc1.=$extras;
2934 $lc2=~ s/^ //g;
2935
2936 $lc2=~ s/ //g;
2937 $extras="";
2938 ##Find the decimal part of $lc2
2939 my $pos=index($lc2,".");
2940 if ($pos<0){$pos=length($lc2);}
2941 if ($pos>=0 && $pos<5){
2942 ##Pad lc2 with zeros to create a 5digit decimal needed in marc record to sort as numeric
2943
2944         for (1..(5-$pos)){
2945         $extras.="0";
2946         }
2947 }
2948 $lc2=$extras.$lc2;
2949 return($lc1.$lc2);
2950 }
2951
2952 sub itemcalculator{
2953 my ($dbh,$biblioitem,$callnumber)=@_;
2954 my $sth=$dbh->prepare("select classification, subclass from biblioitems where biblioitemnumber=?");
2955
2956 $sth->execute($biblioitem);
2957 my ($classification,$subclass)=$sth->fetchrow;
2958 my $all=$classification." ".$subclass;
2959 my $total=length($all);
2960 my $cutterextra=substr($callnumber,$total-1);
2961
2962 return $cutterextra;
2963
2964 }
2965
2966
2967
2968
2969 END { }    # module clean-up code here (global destructor)
2970
2971 =back
2972
2973 =head1 AUTHOR
2974
2975 Koha Developement team <info@koha.org>
2976
2977 Paul POULAIN paul.poulain@free.fr
2978
2979 =cut
2980
2981 # $Id$
2982 # $Log$
2983 # Revision 1.177  2006/08/11 16:04:07  toins
2984 # re-input an old function.
2985 #
2986 # Revision 1.176  2006/08/10 12:44:12  toins
2987 # sync with dev_week.
2988 #
2989 # Revision 1.115.2.51.2.14  2006/07/15 19:22:46  kados
2990 # comment out warns
2991 #
2992 # Revision 1.115.2.51.2.13  2006/07/03 16:05:26  kados
2993 # fix shadow call to ZOOM
2994 #
2995 # Revision 1.115.2.51.2.12  2006/06/02 23:11:23  kados
2996 # Committing my working dev_week. It's been tested only with
2997 # searching, and there's quite a lot of config stuff to set up
2998 # beforehand. As things get closer to a release, we'll be making
2999 # some scripts to do it for us
3000 #
3001 # Revision 1.115.2.51.2.11  2006/05/28 18:49:12  tgarip1957
3002 # This is an unusual commit. The main purpose is a working model of Zebra on a modified rel2_2.
3003 # Any questions regarding these commits should be asked to Joshua Ferraro unless you are Joshua whom I'll report to
3004 #
3005 # Revision 1.115.2.18  2005/08/02 07:45:44  tipaul
3006 # fix for bug http://bugs.koha.org/cgi-bin/bugzilla/show_bug.cgi?id=1009
3007 # (Not all items fields mapped to MARC)
3008 #
3009 # Revision 1.115.2.17  2005/08/01 15:15:43  tipaul
3010 # adding decoder for Ä string
3011 #
3012 # Revision 1.115.2.16  2005/07/28 19:56:15  tipaul
3013 # * removing a useless & CPU consuming call to MARCgetbiblio
3014 # * Leader management.
3015 # If you create a MARC tag "000", with a subfield '@', it will be managed as the leader.
3016 # Seems to work correctly.
3017 #
3018 # Now going to create a plugin for leader()
3019 #
3020 # Revision 1.115.2.15  2005/07/19 15:25:40  tipaul
3021 # * fixing a bug in subfield order when MARCgetbiblio
3022 # * 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.
3023 # * adding some diacritic decoding (Ä, Ü...)
3024 #
3025 # Revision 1.115.2.14  2005/06/27 23:24:06  hdl
3026 # Display dashed ISBN
3027 #
3028 # Revision 1.115.2.13  2005/05/31 12:44:26  tipaul
3029 # patch from Genji (Waylon R.) to update subjects in MARC tables when systempref has MARC=OFF
3030 #
3031 # Revision 1.115.2.12  2005/05/30 11:22:41  tipaul
3032 # 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)
3033 #
3034 # Revision 1.115.2.11  2005/05/25 15:48:43  tipaul
3035 # * removing my for variables already declared
3036 # * updating biblio.unititle  field as well as other fields in biblio table
3037 #
3038 # Revision 1.115.2.10  2005/05/25 09:30:50  hdl
3039 # Adding NEWmodbiblioframework feature
3040 # Used by addbiblio.pl when modifying a framework selection.
3041 #
3042 # Revision 1.115.2.9  2005/04/07 10:05:25  tipaul
3043 # adding / to the list of symbols that are replace by spaces for searches
3044 #
3045 # Revision 1.115.2.8  2005/03/25 16:23:49  tipaul
3046 # some improvements :
3047 # * return immediatly when a subfield is empty
3048 # * search duplicate on isbn must be done only when there is an isbn ;-)
3049 #
3050 # Revision 1.115.2.7  2005/03/10 15:52:28  tipaul
3051 # * adding glass to opac marc detail.
3052 # * 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)
3053 # * fixing bug with libopac
3054 #
3055 # Revision 1.115.2.6  2005/03/09 15:56:01  tipaul
3056 # Changing MARCmoditem to be like MARCmodbiblio : a modif is a delete & create.
3057 # Longer, but solves problems with repeated subfields.
3058 #
3059 # The previous version was not buggy except under certain circumstances (a repeated subfield, that does not exist usually in items)
3060 #
3061 # Revision 1.115.2.5  2005/02/24 13:54:04  tipaul
3062 # exporting MARCdelsubfield sub. It's used in authority merging.
3063 # Modifying it too to enable deletion of all subfields from a given tag/subfield or just one.
3064 #
3065 # Revision 1.115.2.4  2005/02/17 12:44:25  tipaul
3066 # bug in acquisition : the title was also stored as subtitle.
3067 #
3068 # Revision 1.115.2.3  2005/02/10 13:14:36  tipaul
3069 # * multiple main authors are now correctly handled in simple (non-MARC) view
3070 #
3071 # Revision 1.115.2.2  2005/01/11 16:02:35  tipaul
3072 # in catalogue, modifs were not stored properly the non-MARC item DB. Affect only libraries without barcodes.
3073 #
3074 # Revision 1.115.2.1  2005/01/11 14:45:37  tipaul
3075 # bugfix : issn were not stored correctly in non-MARC DB on biblio modification
3076 #
3077 # Revision 1.115  2005/01/06 14:32:17  tipaul
3078 # improvement of speed for bulkmarcimport.
3079 # A sub had been forgotten to use the C4::Context->marcfromkohafield array, that caches DB datas.
3080 # this is only a little improvement for normal DB modif, but almost x2 the speed of bulkmarcimport... from 6records/seconds to more than 10.
3081 #
3082 # Revision 1.114  2005/01/03 10:48:33  tipaul
3083 # * bugfix for the search on a MARC detail, when you clic on the magnifying glass (caused an internal server error)
3084 # * 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.
3085 #
3086 # Revision 1.113  2004/12/10 16:27:53  tipaul
3087 # 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)
3088 # In 2.4, a new DB structure will highly speed things and this limit will be removed.
3089 # FindDuplicate is activated again, the perf problems were due to this problem.
3090 #
3091 # Revision 1.112  2004/12/08 10:14:42  tipaul
3092 # * desactivate FindDuplicate
3093 # * fix from Genji
3094 #
3095 # Revision 1.111  2004/11/25 17:39:44  tipaul
3096 # removing useless &branches in package declaration
3097 #
3098 # Revision 1.110  2004/11/24 16:00:01  tipaul
3099 # removing sub branches (commited by chris for MARC=OFF bugfix, but sub branches is already in Acquisition.pm)
3100 #
3101 # Revision 1.109  2004/11/24 15:58:31  tipaul
3102 # * critical fix for acquisition (see RC3 release notes)
3103 # * critical fix for duplicate finder
3104 #
3105 # Revision 1.108  2004/11/19 19:41:22  rangi
3106 # Shifting branches() from deprecated C4::Catalogue to C4::Biblio
3107 # Allowing the non marc interface acquisitions to work.
3108 #
3109 # Revision 1.107  2004/11/05 10:15:27  tipaul
3110 # Improving FindDuplicate to find duplicate records on adding biblio
3111 #
3112 # Revision 1.106  2004/11/02 16:44:45  tipaul
3113 # new feature : checking for duplicate biblio.
3114 #
3115 # For instance, it's only done on ISBN only. Will be improved soon.
3116 #
3117 # When a duplicate is detected, the biblio is not saved, but the user is asked for a confirmations.
3118 #
3119 # Revision 1.105  2004/09/23 16:15:37  tipaul
3120 # indenting diff
3121 #
3122 # Revision 1.104  2004/09/16 15:06:46  tipaul
3123 # enabling # (| still possible too) for repeatable subfields
3124 #
3125 # Revision 1.103  2004/09/06 14:17:34  tipaul
3126 # some commented warning added + 1 major bugfix => drop empty fields, NOT fields containing 0
3127 #
3128 # Revision 1.102  2004/09/06 10:00:19  tipaul
3129 # adding a "location" field to the library.
3130 # This field is useful when the callnumber contains no information on the room where the item is stored.
3131 # With this field, we now have 3 levels of informations to find a book :
3132 # * the branch.
3133 # * the location.
3134 # * the callnumber.
3135 #
3136 # This should be versatile enough to solve any storing method.
3137 # 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.
3138 #
3139 # Revision 1.101  2004/08/18 16:01:37  tipaul
3140 # modifs to support frameworkcodes
3141 #
3142 # Revision 1.100  2004/08/13 16:37:25  tipaul
3143 # adding frameworkcode to API in some subs
3144 #
3145 # Revision 1.99  2004/07/30 13:54:50  doxulting
3146 # Beginning of serial commit
3147 #
3148 # Revision 1.98  2004/07/15 09:48:10  tipaul
3149 # * removing useless sub
3150 # * minor bugfix in moditem (managing homebranch & holdingbranch)
3151 #
3152 # Revision 1.97  2004/07/02 15:53:53  tipaul
3153 # bugfix (due to frameworkcode field)
3154 #
3155 # Revision 1.96  2004/06/29 16:07:10  tipaul
3156 # last sync for 2.1.0 release
3157 #
3158 # Revision 1.95  2004/06/26 23:19:59  rangi
3159 # Fixing modaddauthor, and adding getitemtypes.
3160 # Also tidying up formatting of code
3161 #
3162 # Revision 1.94  2004/06/17 08:16:32  tipaul
3163 # merging tag & subfield in marc_word for better perfs
3164 #
3165 # Revision 1.93  2004/06/11 15:38:06  joshferraro
3166 # Changes MARCaddword to index words >= 1 char ... needed for more accurate
3167 # searches using SearchMarc routines.
3168 #
3169 # Revision 1.92  2004/06/10 08:29:01  tipaul
3170 # MARC authority management (continued)
3171 #
3172 # Revision 1.91  2004/06/03 10:03:01  tipaul
3173 # * frameworks and itemtypes are independant
3174 # * in the MARC editor, showing the + to duplicate a tag only if the tag is repeatable
3175 #
3176 # Revision 1.90  2004/05/28 08:25:53  tipaul
3177 # hidding hidden & isurl constraints into MARC subfield structure
3178 #
3179 # Revision 1.89  2004/05/27 21:47:21  rangi
3180 # Fix for bug 787
3181 #
3182 # Revision 1.88  2004/05/18 15:23:49  tipaul
3183 # framework management : 1 MARC framework for each itemtype
3184 #
3185 # Revision 1.87  2004/05/18 11:54:07  tipaul
3186 # getitemtypes moved in Koha.pm
3187 #
3188 # Revision 1.86  2004/05/03 09:19:22  tipaul
3189 # some fixes for mysql prepare & execute
3190 #
3191 # Revision 1.85  2004/04/02 14:55:48  tipaul
3192 # renaming items.bulk field to items.itemcallnumber.
3193 # Will be used to store call number for libraries that don't use dewey classification.
3194 # Note it's related to ITEMS, not biblio.
3195 #
3196 # Revision 1.84  2004/03/24 17:18:30  joshferraro
3197 # Fixes bug 749 by removing the comma on line 1488.
3198 #
3199 # Revision 1.83  2004/03/15 14:31:50  tipaul
3200 # adding a minor check
3201 #
3202 # Revision 1.82  2004/03/07 05:47:31  acli
3203 # Various updates/fixes from rel_2_0
3204 # Fixes for bugs 721 (templating), 727, and 734
3205 #
3206 # Revision 1.81  2004/03/06 20:26:13  tipaul
3207 # adding seealso feature in MARC searches
3208 #
3209 # Revision 1.80  2004/02/12 13:40:56  tipaul
3210 # deleting subs duplicated by error
3211 #
3212 # Revision 1.79  2004/02/11 08:40:09  tipaul
3213 # synch'ing 2.0.0 branch and head
3214 #
3215 # Revision 1.78.2.3  2004/02/10 13:15:46  tipaul
3216 # removing 2 warnings
3217 #
3218 # Revision 1.78.2.2  2004/01/26 10:38:06  tipaul
3219 # dealing correctly "bulk" field
3220 #
3221 # Revision 1.78.2.1  2004/01/13 17:29:53  tipaul
3222 # * minor html fixes
3223 # * adding publisher in acquisition process (& ordering basket by publisher)
3224 #
3225 # Revision 1.78  2003/12/09 15:57:28  tipaul
3226 # rolling back to working char_decode sub
3227 #
3228 # Revision 1.77  2003/12/03 17:47:14  tipaul
3229 # bugfixes for biblio deletion
3230 #
3231 # Revision 1.76  2003/12/03 01:43:41  slef
3232 # conflict markers?
3233 #
3234 # Revision 1.75  2003/12/03 01:42:03  slef
3235 # bug 662 fixes securing DBI
3236 #
3237 # Revision 1.74  2003/11/28 09:48:33  tipaul
3238 # bugfix : misusing prepare & execute => now using prepare(?) and execute($var)
3239 #
3240 # Revision 1.73  2003/11/28 09:45:25  tipaul
3241 # bugfix for iso2709 file import in the "notforloan" field.
3242 #
3243 # But notforloan field called "loan" somewhere, so in case "loan" is used, copied to "notforloan" to avoid a bug.
3244 #
3245 # Revision 1.72  2003/11/24 17:40:14  tipaul
3246 # fix for #385
3247 #
3248 # Revision 1.71  2003/11/24 16:28:49  tipaul
3249 # biblio & item deletion now works fine in MARC editor.
3250 # Stores deleted biblio/item in the marc field of the deletedbiblio/deleteditem table.
3251 #
3252 # Revision 1.70  2003/11/24 13:29:55  tipaul
3253 # moving $id from beginning to end of file (70 commits... huge comments...)
3254 #
3255 # Revision 1.69  2003/11/24 13:27:17  tipaul
3256 # fix for #380 (bibliosubject)
3257 #
3258 # Revision 1.68  2003/11/06 17:18:30  tipaul
3259 # bugfix for #384
3260 #
3261 # 1st draft for MARC biblio deletion.
3262 # Still does not work well, but at least, Biblio.pm compiles & it should'nt break too many things
3263 # (Note the trash in the MARCdetail, but don't use it, please :-) )
3264 #
3265 # Revision 1.67  2003/10/25 08:46:27  tipaul
3266 # minor fixes for bilbio deletion (still buggy)
3267 #
3268 # Revision 1.66  2003/10/17 10:02:56  tipaul
3269 # Indexing only words longer than 2 letters. Was >=2 before, & 2 letters words usually means nothing.
3270 #
3271 # Revision 1.65  2003/10/14 09:45:29  tipaul
3272 # 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)
3273 #
3274 # Revision 1.64  2003/10/06 15:20:51  tipaul
3275 # fix for 536 (subtitle error)
3276 #
3277 # Revision 1.63  2003/10/01 13:25:49  tipaul
3278 # seems a char encoding problem modified something in char_decode sub... changing back to something that works...
3279 #
3280 # Revision 1.62  2003/09/17 14:21:13  tipaul
3281 # fixing bug that makes a MARC biblio disappear when using full acquisition (order => recieve ==> MARC editor).
3282 # Before this 2 lines fix, the MARC biblio was deleted during recieve, and had to be entirely recreated :-(
3283 #
3284 # Revision 1.61  2003/09/17 10:24:39  tipaul
3285 # notforloan value in itemtype was overwritting notforloan value in a given item.
3286 # I changed this behaviour :
3287 # if notforloan is set for a given item, and NOT for all items from this itemtype, the notforloan is kept.
3288 # If notforloan is set for itemtype, it's used (and impossible to loan a specific item from this itemtype)
3289 #
3290 # Revision 1.60  2003/09/04 14:11:23  tipaul
3291 # fix for 593 (data duplication in MARC-DB)
3292 #
3293 # Revision 1.58  2003/08/06 12:54:52  tipaul
3294 # fix for publicationyear : extracting numeric value from MARC string, like for copyrightdate.
3295 # (note that copyrightdate still extracted to get numeric format)
3296 #
3297 # Revision 1.57  2003/07/15 23:09:18  slef
3298 # change show columns to use biblioitems bnotes too
3299 #
3300 # Revision 1.56  2003/07/15 11:34:52  slef
3301 # fixes from paul email
3302 #
3303 # Revision 1.55  2003/07/15 00:02:49  slef
3304 # Work on bug 515... can we do a single-side rename of notes to bnotes?
3305 #
3306 # Revision 1.54  2003/07/11 11:51:32  tipaul
3307 # *** empty log message ***
3308 #
3309 # Revision 1.52  2003/07/10 10:37:19  tipaul
3310 # fix for copyrightdate problem, #514
3311 #
3312 # Revision 1.51  2003/07/02 14:47:17  tipaul
3313 # fix for #519 : items.dateaccessioned imports incorrectly
3314 #
3315 # Revision 1.49  2003/06/17 11:21:13  tipaul
3316 # improvments/fixes for z3950 support.
3317 # * Works now even on ADD, not only on MODIFY
3318 # * able to search on ISBN, author, title
3319 #
3320 # Revision 1.48  2003/06/16 09:22:53  rangi
3321 # Just added an order clause to getitemtypes
3322 #
3323 # Revision 1.47  2003/05/20 16:22:44  tipaul
3324 # fixing typo in Biblio.pm POD
3325 #
3326 # Revision 1.46  2003/05/19 13:45:18  tipaul
3327 # support for subtitles, additional authors, subject.
3328 # 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.
3329 # Note that some OLD-DB subs are strange (dummy ?) see OLDmodsubject, OLDmodsubtitle, OLDmodaddiauthor in C4/Biblio.pm
3330 # 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.
3331 #
3332 # Revision 1.45  2003/04/29 16:50:49  tipaul
3333 # really proud of this commit :-)
3334 # z3950 search and import seems to works fine.
3335 # Let me explain how :
3336 # * a "search z3950" button is added in the addbiblio template.
3337 # * when clicked, a popup appears and z3950/search.pl is called
3338 # * z3950/search.pl calls addz3950search in the DB
3339 # * the z3950 daemon retrieve the records and stores them in z3950results AND in marc_breeding table.
3340 # * as long as there as searches pending, the popup auto refresh every 2 seconds, and says how many searches are pending.
3341 # * when the user clicks on a z3950 result => the parent popup is called with the requested biblio, and auto-filled
3342 #
3343 # Note :
3344 # * 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.
3345 # * 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.
3346 #
3347 # Revision 1.44  2003/04/28 13:07:14  tipaul
3348 # Those fixes solves the "internal server error" with MARC::Record 1.12.
3349 # It was due to an illegal contruction in Koha : we tried to retrive subfields from <10 tags.
3350 # That's not possible. MARC::Record accepted this in 0.93 version, but it was fixed after.
3351 # Now, the construct/retrieving is OK !
3352 #
3353 # Revision 1.43  2003/04/10 13:56:02  tipaul
3354 # Fix some bugs :
3355 # * worked in 1.9.0, but not in 1.9.1 :
3356 # - modif of a biblio didn't work
3357 # - 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.
3358 #
3359 # * did not work before :
3360 # - repeatable subfields now works correctly. Enter 2 subfields separated by | and they will be splitted during saving.
3361 # - dropped the last subfield of the MARC form :-(
3362 #
3363 # Internal changes :
3364 # - 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.
3365 # Note the MARCdelbiblio has been rewritted to enable deletion of a biblio WITHOUT deleting items.
3366 #
3367 # Revision 1.42  2003/04/04 08:41:11  tipaul
3368 # last commits before 1.9.1
3369 #
3370 # Revision 1.41  2003/04/01 12:26:43  tipaul
3371 # fixes
3372 #
3373 # Revision 1.40  2003/03/11 15:14:03  tipaul
3374 # pod updating
3375 #
3376 # Revision 1.39  2003/03/07 16:35:42  tipaul
3377 # * moving generic functions to Koha.pm
3378 # * improvement of SearchMarc.pm
3379 # * bugfixes
3380 # * code cleaning
3381 #
3382 # Revision 1.38  2003/02/27 16:51:59  tipaul
3383 # * moving prepare / execute to ? form.
3384 # * some # cleaning
3385 # * little bugfix.
3386 # * road to 1.9.2 => acquisition and cataloguing merging
3387 #
3388 # Revision 1.37  2003/02/12 11:03:03  tipaul
3389 # Support for 000 -> 010 fields.
3390 # Those fields doesn't have subfields.
3391 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3392 # 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.
3393 #
3394 # Revision 1.36  2003/02/12 11:01:01  tipaul
3395 # Support for 000 -> 010 fields.
3396 # Those fields doesn't have subfields.
3397 # In koha, we will use a specific "trick" : fields <10 will have a "virtual" subfield : "@".
3398 # 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.
3399 #
3400 # Revision 1.35  2003/02/03 18:46:00  acli
3401 # Minor factoring in C4/Biblio.pm, plus change to export the per-tag
3402 # 'mandatory' property to a per-subfield 'tag_mandatory' template parameter,
3403 # so that addbiblio.tmpl can distinguish between mandatory subfields in a
3404 # mandatory tag and mandatory subfields in an optional tag
3405 #
3406 # Not-minor factoring in acqui.simple/addbiblio.pl to make the if-else blocks
3407 # smaller, and to add some POD; need further testing for this
3408 #
3409 # Added function to check if a MARC subfield name is "koha-internal" (instead
3410 # of checking it for 'lib' and 'tag' everywhere); temporarily added to Koha.pm
3411 #
3412 # Use above function in acqui.simple/additem.pl and search.marc/search.pl
3413 #
3414 # Revision 1.34  2003/01/28 14:50:04  tipaul
3415 # fixing MARCmodbiblio API and reindenting code
3416 #
3417 # Revision 1.33  2003/01/23 12:22:37  tipaul
3418 # adding char_decode to decode MARC21 or UNIMARC extended chars
3419 #
3420 # Revision 1.32  2002/12/16 15:08:50  tipaul
3421 # small but important bugfix (fixes a problem in export)
3422 #
3423 # Revision 1.31  2002/12/13 16:22:04  tipaul
3424 # 1st draft of marc export
3425 #
3426 # Revision 1.30  2002/12/12 21:26:35  tipaul
3427 # YAB ! (Yet Another Bugfix) => related to biblio modif
3428 # (some warning cleaning too)
3429 #
3430 # Revision 1.29  2002/12/12 16:35:00  tipaul
3431 # adding authentification with Auth.pm and
3432 # MAJOR BUGFIX on marc biblio modification
3433 #
3434 # Revision 1.28  2002/12/10 13:30:03  tipaul
3435 # fugfixes from Dombes Abbey work
3436 #
3437 # Revision 1.27  2002/11/19 12:36:16  tipaul
3438 # road to 1.3.2
3439 # various bugfixes, improvments, and migration from acquisition.pm to biblio.pm
3440 #
3441 # Revision 1.26  2002/11/12 15:58:43  tipaul
3442 # road to 1.3.2 :
3443 # * many bugfixes
3444 # * 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)
3445 #
3446 # Revision 1.25  2002/10/25 10:58:26  tipaul
3447 # Road to 1.3.2
3448 # * bugfixes and improvements
3449 #
3450 # Revision 1.24  2002/10/24 12:09:01  arensb
3451 # Fixed "no title" warning when generating HTML documentation from POD.
3452 #
3453 # Revision 1.23  2002/10/16 12:43:08  arensb
3454 # Added some FIXME comments.
3455 #
3456 # Revision 1.22  2002/10/15 13:39:17  tipaul
3457 # removing Acquisition.pm
3458 # deleting unused code in biblio.pm, rewriting POD and answering most FIXME comments
3459 #
3460 # Revision 1.21  2002/10/13 11:34:14  arensb
3461 # Replaced expressions of the form "$x = $x <op> $y" with "$x <op>= $y".
3462 # Thus, $x = $x+2 becomes $x += 2, and so forth.
3463 #
3464 # Revision 1.20  2002/10/13 08:28:32  arensb
3465 # Deleted unused variables.
3466 # Removed trailing whitespace.
3467 #
3468 # Revision 1.19  2002/10/13 05:56:10  arensb
3469 # Added some FIXME comments.
3470 #
3471 # Revision 1.18  2002/10/11 12:34:53  arensb
3472 # Replaced &requireDBI with C4::Context->dbh
3473 #
3474 # Revision 1.17  2002/10/10 14:48:25  tipaul
3475 # bugfixes
3476 #
3477 # Revision 1.16  2002/10/07 14:04:26  tipaul
3478 # road to 1.3.1 : viewing MARC biblio
3479 #
3480 # Revision 1.15  2002/10/05 09:49:25  arensb
3481 # Merged with arensb-context branch: use C4::Context->dbh instead of
3482 # &C4Connect, and generally prefer C4::Context over C4::Database.
3483 #
3484 # Revision 1.14  2002/10/03 11:28:18  tipaul
3485 # Extending Context.pm to add stopword management and using it in MARC-API.
3486 # First benchmarks show a medium speed improvement, which  is nice as this part is heavily called.
3487 #
3488 # Revision 1.13  2002/10/02 16:26:44  tipaul
3489 # road to 1.3.1
3490 #
3491 # Revision 1.12.2.4  2002/10/05 07:09:31  arensb
3492 # Merged in changes from main branch.
3493 #
3494 # Revision 1.12.2.3  2002/10/05 06:12:10  arensb
3495 # Added a whole mess of FIXME comments.
3496 #
3497 # Revision 1.12.2.2  2002/10/05 04:03:14  arensb
3498 # Added some missing semicolons.
3499 #
3500 # Revision 1.12.2.1  2002/10/04 02:24:01  arensb
3501 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3502 # C4Connect.
3503 #
3504 # Revision 1.12.2.3  2002/10/05 06:12:10  arensb
3505 # Added a whole mess of FIXME comments.
3506 #
3507 # Revision 1.12.2.2  2002/10/05 04:03:14  arensb
3508 # Added some missing semicolons.
3509 #
3510 # Revision 1.12.2.1  2002/10/04 02:24:01  arensb
3511 # Use C4::Connect instead of C4::Database, C4::Connect->dbh instead
3512 # C4Connect.
3513 #
3514 # Revision 1.12  2002/10/01 11:48:51  arensb
3515 # Added some FIXME comments, mostly marking duplicate functions.
3516 #
3517 # Revision 1.11  2002/09/24 13:49:26  tipaul
3518 # long WAS the road to 1.3.0...
3519 # coming VERY SOON NOW...
3520 # modifying installer and buildrelease to update the DB
3521 #
3522 # Revision 1.10  2002/09/22 16:50:08  arensb
3523 # Added some FIXME comments.
3524 #
3525 # Revision 1.9  2002/09/20 12:57:46  tipaul
3526 # long is the road to 1.4.0
3527 # * MARCadditem and MARCmoditem now wroks
3528 # * various bugfixes in MARC management
3529 # !!! 1.3.0 should be released very soon now. Be careful !!!
3530 #
3531 # Revision 1.8  2002/09/10 13:53:52  tipaul
3532 # MARC API continued...
3533 # * some bugfixes
3534 # * 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)
3535 #
3536 # Note : it should not be hard for marcimport and marcexport to re-link fields from internal tag/subfield to "legal" tag/subfield.
3537 #
3538 # Revision 1.7  2002/08/14 18:12:51  tonnesen
3539 # Added copyright statement to all .pl and .pm files
3540 #
3541 # Revision 1.6  2002/07/25 13:40:31  tipaul
3542 # pod documenting the API.
3543 #
3544 # Revision 1.5  2002/07/24 16:11:37  tipaul
3545 # Now, the API...
3546 # Database.pm and Output.pm are almost not modified (var test...)
3547 #
3548 # Biblio.pm is almost completly rewritten.
3549 #
3550 # WHAT DOES IT ??? ==> END of Hitchcock suspens
3551 #
3552 # 1st, it does... nothing...
3553 # 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 ...
3554 #
3555 # All old-API functions have been cloned. for example, the "newbiblio" sub, now has become :
3556 # * a "newbiblio" sub, with the same parameters. It just call a sub named OLDnewbiblio
3557 # * 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.
3558 # * 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.
3559 # 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 ;-)
3560 #
3561 # 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.
3562 # Note we have decided with steve that a old-biblio <=> a MARC-Biblio.
3563 #