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