View | Details | Raw Unified | Return to bug 2060
Collapse All | Expand All

(-)a/C4/AuthoritiesMarc.pm (+64 lines)
Lines 54-59 BEGIN { Link Here
54
        &BuildSummary
54
        &BuildSummary
55
    	&BuildUnimarcHierarchies
55
    	&BuildUnimarcHierarchies
56
    	&BuildUnimarcHierarchy
56
    	&BuildUnimarcHierarchy
57
        &GetAuthorizedHeading
57
    
58
    
58
    	&merge
59
    	&merge
59
    	&FindDuplicateAuthority
60
    	&FindDuplicateAuthority
Lines 1108-1113 sub BuildSummary { Link Here
1108
    return \%summary;
1109
    return \%summary;
1109
}
1110
}
1110
1111
1112
=head2 GetAuthorizedHeading
1113
1114
  $heading = &GetAuthorizedHeading({ record => $record, authid => $authid })
1115
1116
Takes a MARC::Record object describing an authority record or an authid, and
1117
returns a string representation of the first authorized heading. This routine
1118
should be considered a temporary shim to ease the future migration of authority
1119
data from C4::AuthoritiesMarc to the object-oriented Koha::*::Authority.
1120
1121
=cut
1122
1123
sub GetAuthorizedHeading {
1124
    my $args = shift;
1125
    my $record;
1126
    unless ($record = $args->{record}) {
1127
        return unless $args->{authid};
1128
        $record = GetAuthority($args->{authid});
1129
    }
1130
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
1131
# construct UNIMARC summary, that is quite different from MARC21 one
1132
# accepted form
1133
        foreach my $field ($record->field('2..')) {
1134
            return $field->as_string('abcdefghijlmnopqrstuvwxyz');
1135
        }
1136
    } else {
1137
        foreach my $field ($record->field('1..')) {
1138
            my $tag = $field->tag();
1139
            next if "152" eq $tag;
1140
# FIXME - 152 is not a good tag to use
1141
# in MARC21 -- purely local tags really ought to be
1142
# 9XX
1143
            if ($tag eq '100') {
1144
                return $field->as_string('abcdefghjklmnopqrstvxyz68');
1145
            } elsif ($tag eq '110') {
1146
                return $field->as_string('abcdefghklmnoprstvxyz68');
1147
            } elsif ($tag eq '111') {
1148
                return $field->as_string('acdefghklnpqstvxyz68');
1149
            } elsif ($tag eq '130') {
1150
                return $field->as_string('adfghklmnoprstvxyz68');
1151
            } elsif ($tag eq '148') {
1152
                return $field->as_string('abvxyz68');
1153
            } elsif ($tag eq '150') {
1154
                return $field->as_string('abvxyz68');
1155
            } elsif ($tag eq '151') {
1156
                return $field->as_string('avxyz68');
1157
            } elsif ($tag eq '155') {
1158
                return $field->as_string('abvxyz68');
1159
            } elsif ($tag eq '180') {
1160
                return $field->as_string('vxyz68');
1161
            } elsif ($tag eq '181') {
1162
                return $field->as_string('vxyz68');
1163
            } elsif ($tag eq '182') {
1164
                return $field->as_string('vxyz68');
1165
            } elsif ($tag eq '185') {
1166
                return $field->as_string('vxyz68');
1167
            } else {
1168
                return $field->as_string();
1169
            }
1170
        }
1171
    }
1172
    return;
1173
}
1174
1111
=head2 BuildUnimarcHierarchies
1175
=head2 BuildUnimarcHierarchies
1112
1176
1113
  $text= &BuildUnimarcHierarchies( $authid, $force)
1177
  $text= &BuildUnimarcHierarchies( $authid, $force)
(-)a/C4/ImportBatch.pm (-112 / +238 lines)
Lines 1-6 Link Here
1
package C4::ImportBatch;
1
package C4::ImportBatch;
2
2
3
# Copyright (C) 2007 LibLime
3
# Copyright (C) 2007 LibLime, 2012 C & P Bibliography Services
4
#
4
#
5
# This file is part of Koha.
5
# This file is part of Koha.
6
#
6
#
Lines 25-30 use C4::Koha; Link Here
25
use C4::Biblio;
25
use C4::Biblio;
26
use C4::Items;
26
use C4::Items;
27
use C4::Charset;
27
use C4::Charset;
28
use C4::AuthoritiesMarc;
28
29
29
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
30
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
30
31
Lines 40-60 BEGIN { Link Here
40
    GetImportRecordMarcXML
41
    GetImportRecordMarcXML
41
    AddImportBatch
42
    AddImportBatch
42
    GetImportBatch
43
    GetImportBatch
44
    AddAuthToBatch
43
    AddBiblioToBatch
45
    AddBiblioToBatch
44
    AddItemsToImportBiblio
46
    AddItemsToImportBiblio
47
    ModAuthorityInBatch
45
    ModBiblioInBatch
48
    ModBiblioInBatch
46
49
47
    BatchStageMarcRecords
50
    BatchStageMarcRecords
48
    BatchFindBibDuplicates
51
    BatchFindDuplicates
49
    BatchCommitBibRecords
52
    BatchCommitRecords
50
    BatchRevertBibRecords
53
    BatchRevertRecords
51
    CleanBatch
54
    CleanBatch
52
55
53
    GetAllImportBatches
56
    GetAllImportBatches
54
    GetStagedWebserviceBatches
57
    GetStagedWebserviceBatches
55
    GetImportBatchRangeDesc
58
    GetImportBatchRangeDesc
56
    GetNumberOfNonZ3950ImportBatches
59
    GetNumberOfNonZ3950ImportBatches
57
    GetImportBibliosRange
60
    GetImportRecordsRange
58
	GetItemNumbersFromImportBatch
61
	GetItemNumbersFromImportBatch
59
    
62
    
60
    GetImportBatchStatus
63
    GetImportBatchStatus
Lines 272-281 sub ModBiblioInBatch { Link Here
272
275
273
}
276
}
274
277
278
=head2 AddAuthToBatch
279
280
  my $import_record_id = AddAuthToBatch($batch_id, $record_sequence,
281
                $marc_record, $encoding, $z3950random, $update_counts);
282
283
=cut
284
285
sub AddAuthToBatch {
286
    my $batch_id = shift;
287
    my $record_sequence = shift;
288
    my $marc_record = shift;
289
    my $encoding = shift;
290
    my $z3950random = shift;
291
    my $update_counts = @_ ? shift : 1;
292
293
    my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'auth', $encoding, $z3950random);
294
    _add_auth_fields($import_record_id, $marc_record);
295
    _update_batch_record_counts($batch_id) if $update_counts;
296
    return $import_record_id;
297
}
298
299
=head2 ModAuthInBatch
300
301
  ModAuthInBatch($import_record_id, $marc_record);
302
303
=cut
304
305
sub ModAuthInBatch {
306
    my ($import_record_id, $marc_record) = @_;
307
308
    _update_import_record_marc($import_record_id, $marc_record);
309
310
}
311
275
=head2 BatchStageMarcRecords
312
=head2 BatchStageMarcRecords
276
313
277
  ($batch_id, $num_records, $num_items, @invalid_records) = 
314
  ($batch_id, $num_records, $num_items, @invalid_records) = 
278
    BatchStageMarcRecords($encoding, $marc_records, $file_name, 
315
    BatchStageMarcRecords($record_type, $encoding, $marc_records, $file_name,
279
                          $comments, $branch_code, $parse_items,
316
                          $comments, $branch_code, $parse_items,
280
                          $leave_as_staging, 
317
                          $leave_as_staging, 
281
                          $progress_interval, $progress_callback);
318
                          $progress_interval, $progress_callback);
Lines 283-288 sub ModBiblioInBatch { Link Here
283
=cut
320
=cut
284
321
285
sub  BatchStageMarcRecords {
322
sub  BatchStageMarcRecords {
323
    my $record_type = shift;
286
    my $encoding = shift;
324
    my $encoding = shift;
287
    my $marc_records = shift;
325
    my $marc_records = shift;
288
    my $file_name = shift;
326
    my $file_name = shift;
Lines 338-347 sub BatchStageMarcRecords { Link Here
338
            push @invalid_records, $marc_blob;
376
            push @invalid_records, $marc_blob;
339
        } else {
377
        } else {
340
            $num_valid++;
378
            $num_valid++;
341
            $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
379
            if ($record_type eq 'biblio') {
342
            if ($parse_items) {
380
                $import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
343
                my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
381
                if ($parse_items) {
344
                $num_items += scalar(@import_items_ids);
382
                    my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, 0);
383
                    $num_items += scalar(@import_items_ids);
384
                }
385
            } elsif ($record_type eq 'auth') {
386
                $import_record_id = AddAuthToBatch($batch_id, $rec_num, $marc_record, $encoding, int(rand(99999)), 0);
345
            }
387
            }
346
        }
388
        }
347
    }
389
    }
Lines 392-400 sub AddItemsToImportBiblio { Link Here
392
    return @import_items_ids;
434
    return @import_items_ids;
393
}
435
}
394
436
395
=head2 BatchFindBibDuplicates
437
=head2 BatchFindDuplicates
396
438
397
  my $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher, 
439
  my $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
398
             $max_matches, $progress_interval, $progress_callback);
440
             $max_matches, $progress_interval, $progress_callback);
399
441
400
Goes through the records loaded in the batch and attempts to 
442
Goes through the records loaded in the batch and attempts to 
Lines 412-418 singular argument. Link Here
412
454
413
=cut
455
=cut
414
456
415
sub BatchFindBibDuplicates {
457
sub BatchFindDuplicates {
416
    my $batch_id = shift;
458
    my $batch_id = shift;
417
    my $matcher = shift;
459
    my $matcher = shift;
418
    my $max_matches = @_ ? shift : 10;
460
    my $max_matches = @_ ? shift : 10;
Lines 430-438 sub BatchFindBibDuplicates { Link Here
430
472
431
    my $dbh = C4::Context->dbh;
473
    my $dbh = C4::Context->dbh;
432
474
433
    my $sth = $dbh->prepare("SELECT import_record_id, marc
475
    my $sth = $dbh->prepare("SELECT import_record_id, record_type, marc
434
                             FROM import_records
476
                             FROM import_records
435
                             JOIN import_biblios USING (import_record_id)
436
                             WHERE import_batch_id = ?");
477
                             WHERE import_batch_id = ?");
437
    $sth->execute($batch_id);
478
    $sth->execute($batch_id);
438
    my $num_with_matches = 0;
479
    my $num_with_matches = 0;
Lines 460-474 sub BatchFindBibDuplicates { Link Here
460
    return $num_with_matches;
501
    return $num_with_matches;
461
}
502
}
462
503
463
=head2 BatchCommitBibRecords
504
=head2 BatchCommitRecords
464
505
465
  my ($num_added, $num_updated, $num_items_added, $num_items_errored, 
506
  my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) =
466
      $num_ignored) = BatchCommitBibRecords($batch_id, $framework,
507
        BatchCommitRecords($batch_id, $framework,
467
                      $progress_interval, $progress_callback);
508
        $progress_interval, $progress_callback);
468
509
469
=cut
510
=cut
470
511
471
sub BatchCommitBibRecords {
512
sub BatchCommitRecords {
472
    my $batch_id = shift;
513
    my $batch_id = shift;
473
    my $framework = shift;
514
    my $framework = shift;
474
515
Lines 483-507 sub BatchCommitBibRecords { Link Here
483
        $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
524
        $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
484
    }
525
    }
485
526
527
    my $record_type;
486
    my $num_added = 0;
528
    my $num_added = 0;
487
    my $num_updated = 0;
529
    my $num_updated = 0;
488
    my $num_items_added = 0;
530
    my $num_items_added = 0;
489
    my $num_items_errored = 0;
531
    my $num_items_errored = 0;
490
    my $num_ignored = 0;
532
    my $num_ignored = 0;
491
    # commit (i.e., save, all records in the batch)
533
    # commit (i.e., save, all records in the batch)
492
    # FIXME biblio only at the moment
493
    SetImportBatchStatus('importing');
534
    SetImportBatchStatus('importing');
494
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
535
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
495
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
536
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
496
    my $item_action = GetImportBatchItemAction($batch_id);
537
    my $item_action = GetImportBatchItemAction($batch_id);
538
    my $item_tag;
539
    my $item_subfield;
497
    my $dbh = C4::Context->dbh;
540
    my $dbh = C4::Context->dbh;
498
    my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marc, encoding
541
    my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marc, encoding
499
                             FROM import_records
542
                             FROM import_records
500
                             JOIN import_biblios USING (import_record_id)
543
                             LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
544
                             LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
501
                             WHERE import_batch_id = ?");
545
                             WHERE import_batch_id = ?");
502
    $sth->execute($batch_id);
546
    $sth->execute($batch_id);
503
    my $rec_num = 0;
547
    my $rec_num = 0;
504
    while (my $rowref = $sth->fetchrow_hashref) {
548
    while (my $rowref = $sth->fetchrow_hashref) {
549
        $record_type = $rowref->{'record_type'};
505
        $rec_num++;
550
        $rec_num++;
506
        if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
551
        if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
507
            &$progress_callback($rec_num);
552
            &$progress_callback($rec_num);
Lines 513-579 sub BatchCommitBibRecords { Link Here
513
558
514
        my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
559
        my $marc_record = MARC::Record->new_from_usmarc($rowref->{'marc'});
515
560
516
        # remove any item tags - rely on BatchCommitItems
561
        if ($record_type eq 'biblio') {
517
        my ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
562
            # remove any item tags - rely on BatchCommitItems
518
        foreach my $item_field ($marc_record->field($item_tag)) {
563
            ($item_tag,$item_subfield) = &GetMarcFromKohaField("items.itemnumber",'');
519
            $marc_record->delete_field($item_field);
564
            foreach my $item_field ($marc_record->field($item_tag)) {
565
                $marc_record->delete_field($item_field);
566
            }
520
        }
567
        }
521
568
522
        # decide what what to do with the bib and item records
569
        my ($record_result, $item_result, $record_match) =
523
        my ($bib_result, $item_result, $bib_match) = 
524
            _get_commit_action($overlay_action, $nomatch_action, $item_action, 
570
            _get_commit_action($overlay_action, $nomatch_action, $item_action, 
525
                               $rowref->{'overlay_status'}, $rowref->{'import_record_id'});
571
                               $rowref->{'overlay_status'}, $rowref->{'import_record_id'}, $record_type);
526
572
527
        if ($bib_result eq 'create_new') {
573
        my $recordid;
574
        my $query;
575
        if ($record_result eq 'create_new') {
528
            $num_added++;
576
            $num_added++;
529
            my ($biblionumber, $biblioitemnumber) = AddBiblio($marc_record, $framework);
577
            if ($record_type eq 'biblio') {
530
            my $sth = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
578
                my $biblioitemnumber;
531
            $sth->execute($biblionumber, $rowref->{'import_record_id'});
579
                ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework);
532
            $sth->finish();
580
                $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
533
            if ($item_result eq 'create_new') {
581
                if ($item_result eq 'create_new') {
534
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
582
                    my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid);
535
                $num_items_added += $bib_items_added;
583
                    $num_items_added += $bib_items_added;
536
                $num_items_errored += $bib_items_errored;
584
                    $num_items_errored += $bib_items_errored;
585
                }
586
            } else {
587
                my $authid = AddAuthority($marc_record, undef, GuessAuthTypeCode($marc_record));
588
                $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
537
            }
589
            }
590
            my $sth = $dbh->prepare_cached($query);
591
            $sth->execute($recordid, $rowref->{'import_record_id'});
592
            $sth->finish();
538
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
593
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
539
        } elsif ($bib_result eq 'replace') {
594
        } elsif ($record_result eq 'replace') {
540
            $num_updated++;
595
            $num_updated++;
541
            my $biblionumber = $bib_match;
596
            $recordid = $record_match;
542
            my ($count, $oldbiblio) = GetBiblio($biblionumber);
597
            my $oldxml;
543
            my $oldxml = GetXmlBiblio($biblionumber);
598
            if ($record_type eq 'biblio') {
544
599
                my ($count, $oldbiblio) = GetBiblio($recordid);
545
            # remove item fields so that they don't get
600
                $oldxml = GetXmlBiblio($recordid);
546
            # added again if record is reverted
601
547
            my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'});
602
                # remove item fields so that they don't get
548
            foreach my $item_field ($old_marc->field($item_tag)) {
603
                # added again if record is reverted
549
                $old_marc->delete_field($item_field);
604
                my $old_marc = MARC::Record->new_from_xml(StripNonXmlChars($oldxml), 'UTF-8', $rowref->{'encoding'});
550
            }
605
                foreach my $item_field ($old_marc->field($item_tag)) {
606
                    $old_marc->delete_field($item_field);
607
                }
608
                $oldxml = $old_marc->as_xml();
609
610
                ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'});
611
                $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?";
612
613
                if ($item_result eq 'create_new') {
614
                    my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid);
615
                    $num_items_added += $bib_items_added;
616
                    $num_items_errored += $bib_items_errored;
617
                }
618
            } else {
619
                my $oldxml = GetAuthorityXML($recordid);
551
620
552
            ModBiblio($marc_record, $biblionumber, $oldbiblio->{'frameworkcode'});
621
                ModAuthority($recordid, $marc_record, GuessAuthTypeCode($marc_record));
622
                $query = "UPDATE import_auths SET matched_authid = ? WHERE import_record_id = ?";
623
            }
553
            my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
624
            my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
554
            $sth->execute($old_marc->as_xml(), $rowref->{'import_record_id'});
625
            $sth->execute($oldxml, $rowref->{'import_record_id'});
555
            $sth->finish();
626
            $sth->finish();
556
            my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
627
            my $sth2 = $dbh->prepare_cached($query);
557
            $sth2->execute($biblionumber, $rowref->{'import_record_id'});
628
            $sth2->execute($recordid, $rowref->{'import_record_id'});
558
            $sth2->finish();
629
            $sth2->finish();
559
            if ($item_result eq 'create_new') {
560
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
561
                $num_items_added += $bib_items_added;
562
                $num_items_errored += $bib_items_errored;
563
            }
564
            SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
630
            SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
565
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
631
            SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
566
        } elsif ($bib_result eq 'ignore') {
632
        } elsif ($record_result eq 'ignore') {
567
            $num_ignored++;
633
            $num_ignored++;
568
            my $biblionumber = $bib_match;
634
            if ($record_type eq 'biblio' and defined $recordid and $item_result eq 'create_new') {
569
            if (defined $biblionumber and $item_result eq 'create_new') {
635
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid);
570
                my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $biblionumber);
571
                $num_items_added += $bib_items_added;
636
                $num_items_added += $bib_items_added;
572
                $num_items_errored += $bib_items_errored;
637
                $num_items_errored += $bib_items_errored;
573
                # still need to record the matched biblionumber so that the
638
                # still need to record the matched biblionumber so that the
574
                # items can be reverted
639
                # items can be reverted
575
                my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
640
                my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
576
                $sth2->execute($biblionumber, $rowref->{'import_record_id'});
641
                $sth2->execute($recordid, $rowref->{'import_record_id'});
577
                SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
642
                SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
578
            }
643
            }
579
            SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
644
            SetImportRecordStatus($rowref->{'import_record_id'}, 'ignored');
Lines 632-694 sub BatchCommitItems { Link Here
632
    return ($num_items_added, $num_items_errored);
697
    return ($num_items_added, $num_items_errored);
633
}
698
}
634
699
635
=head2 BatchRevertBibRecords
700
=head2 BatchRevertRecords
636
701
637
  my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, 
702
  my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, 
638
      $num_ignored) = BatchRevertBibRecords($batch_id);
703
      $num_ignored) = BatchRevertRecords($batch_id);
639
704
640
=cut
705
=cut
641
706
642
sub BatchRevertBibRecords {
707
sub BatchRevertRecords {
643
    my $batch_id = shift;
708
    my $batch_id = shift;
644
709
710
    my $record_type;
645
    my $num_deleted = 0;
711
    my $num_deleted = 0;
646
    my $num_errors = 0;
712
    my $num_errors = 0;
647
    my $num_reverted = 0;
713
    my $num_reverted = 0;
648
    my $num_items_deleted = 0;
649
    my $num_ignored = 0;
714
    my $num_ignored = 0;
715
    my $num_items_deleted = 0;
650
    # commit (i.e., save, all records in the batch)
716
    # commit (i.e., save, all records in the batch)
651
    # FIXME biblio only at the moment
652
    SetImportBatchStatus('reverting');
717
    SetImportBatchStatus('reverting');
653
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
718
    my $overlay_action = GetImportBatchOverlayAction($batch_id);
654
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
719
    my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
655
    my $dbh = C4::Context->dbh;
720
    my $dbh = C4::Context->dbh;
656
    my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marcxml_old, encoding, matched_biblionumber
721
    my $sth = $dbh->prepare("SELECT import_records.import_record_id, record_type, status, overlay_status, marcxml_old, encoding, matched_biblionumber, matched_authid
657
                             FROM import_records
722
                             FROM import_records
658
                             JOIN import_biblios USING (import_record_id)
723
                             LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
724
                             LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
659
                             WHERE import_batch_id = ?");
725
                             WHERE import_batch_id = ?");
660
    $sth->execute($batch_id);
726
    $sth->execute($batch_id);
661
    while (my $rowref = $sth->fetchrow_hashref) {
727
    while (my $rowref = $sth->fetchrow_hashref) {
728
        $record_type = $rowref->{'record_type'};
662
        if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
729
        if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
663
            $num_ignored++;
730
            $num_ignored++;
664
            next;
731
            next;
665
        }
732
        }
666
733
667
        my $bib_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
734
        my $record_result = _get_revert_action($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
668
735
669
        if ($bib_result eq 'delete') {
736
        if ($record_result eq 'delete') {
670
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
737
            my $error = undef;
671
            my $error = DelBiblio($rowref->{'matched_biblionumber'});
738
            if  ($record_type eq 'biblio') {
739
                $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
740
                $error = DelBiblio($rowref->{'matched_biblionumber'});
741
            } else {
742
                my $deletedauthid = DelAuthority($rowref->{'matched_authid'});
743
            }
672
            if (defined $error) {
744
            if (defined $error) {
673
                $num_errors++;
745
                $num_errors++;
674
            } else {
746
            } else {
675
                $num_deleted++;
747
                $num_deleted++;
676
                SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
748
                SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
677
            }
749
            }
678
        } elsif ($bib_result eq 'restore') {
750
        } elsif ($record_result eq 'restore') {
679
            $num_reverted++;
751
            $num_reverted++;
680
            my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'});
752
            my $old_record = MARC::Record->new_from_xml(StripNonXmlChars($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'});
681
            my $biblionumber = $rowref->{'matched_biblionumber'};
753
            if ($record_type eq 'biblio') {
682
            my ($count, $oldbiblio) = GetBiblio($biblionumber);
754
                my $biblionumber = $rowref->{'matched_biblionumber'};
683
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
755
                my ($count, $oldbiblio) = GetBiblio($biblionumber);
684
            ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
756
                $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
757
                ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
758
            } else {
759
                my $authid = $rowref->{'matched_authid'};
760
                ModAuthority($authid, $old_record, GuessAuthTypeCode($old_record));
761
            }
685
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
762
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
686
        } elsif ($bib_result eq 'ignore') {
763
        } elsif ($record_result eq 'ignore') {
687
            $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
764
            if ($record_type eq 'biblio') {
765
                $num_items_deleted += BatchRevertItems($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
766
            }
688
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
767
            SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
689
        }
768
        }
690
        # remove matched_biblionumber only if there is no 'imported' item left
769
        my $query;
691
        my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?  AND NOT EXISTS (SELECT * FROM import_items WHERE import_items.import_record_id=import_biblios.import_record_id and status='imported')" );
770
        if ($record_type eq 'biblio') {
771
            # remove matched_biblionumber only if there is no 'imported' item left
772
            $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?";
773
            $query = "UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?  AND NOT EXISTS (SELECT * FROM import_items WHERE import_items.import_record_id=import_biblios.import_record_id and status='imported')";
774
        } else {
775
            $query = "UPDATE import_auths SET matched_authid = NULL WHERE import_record_id = ?";
776
        }
777
        my $sth2 = $dbh->prepare_cached($query);
692
        $sth2->execute($rowref->{'import_record_id'});
778
        $sth2->execute($rowref->{'import_record_id'});
693
    }
779
    }
694
780
Lines 862-885 sub GetNumberOfNonZ3950ImportBatches { Link Here
862
    return $count;
948
    return $count;
863
}
949
}
864
950
865
=head2 GetImportBibliosRange
951
=head2 GetImportRecordsRange
866
952
867
  my $results = GetImportBibliosRange($batch_id, $offset, $results_per_group);
953
  my $results = GetImportRecordsRange($batch_id, $offset, $results_per_group);
868
954
869
Returns a reference to an array of hash references corresponding to
955
Returns a reference to an array of hash references corresponding to
870
import_biblios/import_records rows for a given batch
956
import_biblios/import_auths/import_records rows for a given batch
871
starting at the given offset.
957
starting at the given offset.
872
958
873
=cut
959
=cut
874
960
875
sub GetImportBibliosRange {
961
sub GetImportRecordsRange {
876
    my ($batch_id, $offset, $results_per_group, $status) = @_;
962
    my ($batch_id, $offset, $results_per_group, $status) = @_;
877
963
878
    my $dbh = C4::Context->dbh;
964
    my $dbh = C4::Context->dbh;
879
    my $query = "SELECT title, author, isbn, issn, import_record_id, record_sequence,
965
    my $query = "SELECT title, author, isbn, issn, authorized_heading, import_records.import_record_id,
880
                                           status, overlay_status, matched_biblionumber
966
                                           record_sequence, status, overlay_status,
967
                                           matched_biblionumber, matched_authid, record_type
881
                                    FROM   import_records
968
                                    FROM   import_records
882
                                    JOIN   import_biblios USING (import_record_id)
969
                                    LEFT JOIN import_auths ON (import_records.import_record_id=import_auths.import_record_id)
970
                                    LEFT JOIN import_biblios ON (import_records.import_record_id=import_biblios.import_record_id)
883
                                    WHERE  import_batch_id = ?";
971
                                    WHERE  import_batch_id = ?";
884
    my @params;
972
    my @params;
885
    push(@params, $batch_id);
973
    push(@params, $batch_id);
Lines 1181-1196 sub GetImportRecordMatches { Link Here
1181
1269
1182
    my $dbh = C4::Context->dbh;
1270
    my $dbh = C4::Context->dbh;
1183
    # FIXME currently biblio only
1271
    # FIXME currently biblio only
1184
    my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber, score
1272
    my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber,
1273
                                    candidate_match_id, score, record_type
1185
                                    FROM import_records
1274
                                    FROM import_records
1186
                                    JOIN import_record_matches USING (import_record_id)
1275
                                    JOIN import_record_matches USING (import_record_id)
1187
                                    JOIN biblio ON (biblionumber = candidate_match_id)
1276
                                    LEFT JOIN biblio ON (biblionumber = candidate_match_id)
1188
                                    WHERE import_record_id = ?
1277
                                    WHERE import_record_id = ?
1189
                                    ORDER BY score DESC, biblionumber DESC");
1278
                                    ORDER BY score DESC, biblionumber DESC");
1190
    $sth->bind_param(1, $import_record_id);
1279
    $sth->bind_param(1, $import_record_id);
1191
    my $results = [];
1280
    my $results = [];
1192
    $sth->execute();
1281
    $sth->execute();
1193
    while (my $row = $sth->fetchrow_hashref) {
1282
    while (my $row = $sth->fetchrow_hashref) {
1283
        if ($row->{'record_type'} eq 'auth') {
1284
            $row->{'authorized_heading'} = GetAuthorizedHeading( { authid => $row->{'candidate_match_id'} } );
1285
        }
1286
        next if ($row->{'record_type'} eq 'biblio' && not $row->{'biblionumber'});
1194
        push @$results, $row;
1287
        push @$results, $row;
1195
        last if $best_only;
1288
        last if $best_only;
1196
    }
1289
    }
Lines 1250-1255 sub _update_import_record_marc { Link Here
1250
    $sth->finish();
1343
    $sth->finish();
1251
}
1344
}
1252
1345
1346
sub _add_auth_fields {
1347
    my ($import_record_id, $marc_record) = @_;
1348
1349
    my $controlnumber;
1350
    if ($marc_record->field('001')) {
1351
        $controlnumber = $marc_record->field('001')->data();
1352
    }
1353
    my $authorized_heading = GetAuthorizedHeading($marc_record);
1354
    my $dbh = C4::Context->dbh;
1355
    my $sth = $dbh->prepare("INSERT INTO import_auths (import_record_id, controlnumber, authorized_heading) VALUES (?, ?, ?)");
1356
    $sth->execute($import_record_id, $controlnumber, $authorized_heading);
1357
    $sth->finish();
1358
}
1359
1253
sub _add_biblio_fields {
1360
sub _add_biblio_fields {
1254
    my ($import_record_id, $marc_record) = @_;
1361
    my ($import_record_id, $marc_record) = @_;
1255
1362
Lines 1293-1299 sub _update_batch_record_counts { Link Here
1293
1400
1294
    my $dbh = C4::Context->dbh;
1401
    my $dbh = C4::Context->dbh;
1295
    my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1402
    my $sth = $dbh->prepare_cached("UPDATE import_batches SET
1296
                                        num_biblios = (
1403
                                        num_records = (
1297
                                            SELECT COUNT(*)
1404
                                            SELECT COUNT(*)
1298
                                            FROM import_records
1405
                                            FROM import_records
1299
                                            WHERE import_batch_id = import_batches.import_batch_id
1406
                                            WHERE import_batch_id = import_batches.import_batch_id
Lines 1311-1336 sub _update_batch_record_counts { Link Here
1311
}
1418
}
1312
1419
1313
sub _get_commit_action {
1420
sub _get_commit_action {
1314
    my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id) = @_;
1421
    my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id, $record_type) = @_;
1315
    
1422
    
1316
    my ($bib_result, $bib_match, $item_result);
1423
    if ($record_type eq 'biblio') {
1317
1424
        my ($bib_result, $bib_match, $item_result);
1318
    if ($overlay_status ne 'no_match') {
1425
1319
        $bib_match = GetBestRecordMatch($import_record_id);
1426
        if ($overlay_status ne 'no_match') {
1320
        if ($overlay_action eq 'replace') {
1427
            $bib_match = GetBestRecordMatch($import_record_id);
1321
            $bib_result  = defined($bib_match) ? 'replace' : 'create_new';
1428
            if ($overlay_action eq 'replace') {
1322
        } elsif ($overlay_action eq 'create_new') {
1429
                $bib_result  = defined($bib_match) ? 'replace' : 'create_new';
1323
            $bib_result  = 'create_new';
1430
            } elsif ($overlay_action eq 'create_new') {
1324
        } elsif ($overlay_action eq 'ignore') {
1431
                $bib_result  = 'create_new';
1325
            $bib_result  = 'ignore';
1432
            } elsif ($overlay_action eq 'ignore') {
1326
        } 
1433
                $bib_result  = 'ignore';
1327
        $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_matches') ? 'create_new' : 'ignore';
1434
            }
1328
    } else {
1435
            $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_matches') ? 'create_new' : 'ignore';
1329
        $bib_result = $nomatch_action;
1436
        } else {
1330
        $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new')     ? 'create_new' : 'ignore';
1437
            $bib_result = $nomatch_action;
1331
    }
1438
            $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new')     ? 'create_new' : 'ignore';
1439
        }
1440
        return ($bib_result, $item_result, $bib_match);
1441
    } else { # must be auths
1442
        my ($auth_result, $auth_match);
1443
1444
        if ($overlay_status ne 'no_match') {
1445
            $auth_match = GetBestRecordMatch($import_record_id);
1446
            if ($overlay_action eq 'replace') {
1447
                $auth_result  = defined($auth_match) ? 'replace' : 'create_new';
1448
            } elsif ($overlay_action eq 'create_new') {
1449
                $auth_result  = 'create_new';
1450
            } elsif ($overlay_action eq 'ignore') {
1451
                $auth_result  = 'ignore';
1452
            }
1453
        } else {
1454
            $auth_result = $nomatch_action;
1455
        }
1332
1456
1333
    return ($bib_result, $item_result, $bib_match);
1457
        return ($auth_result, undef, $auth_match);
1458
1459
    }
1334
}
1460
}
1335
1461
1336
sub _get_revert_action {
1462
sub _get_revert_action {
(-)a/C4/Matcher.pm (-15 / +63 lines)
Lines 1-6 Link Here
1
package C4::Matcher;
1
package C4::Matcher;
2
2
3
# Copyright (C) 2007 LibLime
3
# Copyright (C) 2007 LibLime, 2012 C & P Bibliography Services
4
#
4
#
5
# This file is part of Koha.
5
# This file is part of Koha.
6
#
6
#
Lines 22-29 use warnings; Link Here
22
22
23
use C4::Context;
23
use C4::Context;
24
use MARC::Record;
24
use MARC::Record;
25
use C4::Search;
26
use C4::Biblio;
27
25
28
use vars qw($VERSION);
26
use vars qw($VERSION);
29
27
Lines 384-389 sub delete { Link Here
384
    $sth->execute($matcher_id); # relying on cascading deletes to clean up everything
382
    $sth->execute($matcher_id); # relying on cascading deletes to clean up everything
385
}
383
}
386
384
385
=head2 record_type
386
387
  $matcher->record_type('biblio');
388
  my $record_type = $matcher->record_type();
389
390
Accessor method.
391
392
=cut
393
394
sub record_type {
395
    my $self = shift;
396
    @_ ? $self->{'record_type'} = shift : $self->{'record_type'};
397
}
398
387
=head2 threshold
399
=head2 threshold
388
400
389
  $matcher->threshold(1000);
401
  $matcher->threshold(1000);
Lines 582-588 sub add_simple_required_check { Link Here
582
    );
594
    );
583
}
595
}
584
596
585
=head2 find_matches
597
=head2 get_matches
586
598
587
  my @matches = $matcher->get_matches($marc_record, $max_matches);
599
  my @matches = $matcher->get_matches($marc_record, $max_matches);
588
  foreach $match (@matches) {
600
  foreach $match (@matches) {
Lines 618-626 sub get_matches { Link Here
618
        my @source_keys = _get_match_keys($source_record, $matchpoint);
630
        my @source_keys = _get_match_keys($source_record, $matchpoint);
619
        next if scalar(@source_keys) == 0;
631
        next if scalar(@source_keys) == 0;
620
        # build query
632
        # build query
621
        my $query = join(" or ", map { "$matchpoint->{'index'}=$_" } @source_keys);
633
        my $query;
622
        # FIXME only searching biblio index at the moment
634
        my $error;
623
        my ($error, $searchresults, $total_hits) = SimpleSearch($query, 0, $max_matches);
635
        my $searchresults;
636
        my $total_hits;
637
        if ($self->{'record_type'} eq 'biblio') {
638
            $query = join(" or ", map { "$matchpoint->{'index'}=$_" } @source_keys);
639
# FIXME only searching biblio index at the moment
640
            require C4::Search;
641
            ($error, $searchresults, $total_hits) = C4::Search::SimpleSearch($query, 0, $max_matches);
642
        } elsif ($self->{'record_type'} eq 'authority') {
643
            my $authresults;
644
            my @marclist;
645
            my @and_or;
646
            my @excluding = [];
647
            my @operator;
648
            my @value;
649
            foreach my $key (@source_keys) {
650
                push @marclist, $matchpoint->{'index'};
651
                push @and_or, 'or';
652
                push @operator, 'exact';
653
                push @value, $key;
654
            }
655
            require C4::AuthoritiesMarc;
656
            ($authresults, $total_hits) = C4::AuthoritiesMarc::SearchAuthorities(
657
                    \@marclist, \@and_or, \@excluding, \@operator,
658
                    \@value, 0, 20, undef, 'AuthidAsc', 1
659
            );
660
            foreach my $result (@$authresults) {
661
                push @$searchresults, $result->{'authid'};
662
            }
663
        }
624
664
625
        if (defined $error ) {
665
        if (defined $error ) {
626
            warn "search failed ($query) $error";
666
            warn "search failed ($query) $error";
Lines 636-651 sub get_matches { Link Here
636
676
637
    # get rid of any that don't meet the required checks
677
    # get rid of any that don't meet the required checks
638
    %matches = map { _passes_required_checks($source_record, $_, $self->{'required_checks'}) ?  ($_ => $matches{$_}) : () } 
678
    %matches = map { _passes_required_checks($source_record, $_, $self->{'required_checks'}) ?  ($_ => $matches{$_}) : () } 
639
                keys %matches;
679
                keys %matches unless ($self->{'record_type'} eq 'auth');
640
680
641
    my @results = ();
681
    my @results = ();
642
    foreach my $marcblob (keys %matches) {
682
    if ($self->{'record_type'} eq 'biblio') {
643
        my $target_record = MARC::Record->new_from_usmarc($marcblob);
683
        require C4::Biblio;
644
        my $result = TransformMarcToKoha(C4::Context->dbh, $target_record, '');
684
        foreach my $marcblob (keys %matches) {
645
        # FIXME - again, bibliospecific
685
            my $target_record = MARC::Record->new_from_usmarc($marcblob);
646
        # also, can search engine be induced to give just the number in the first place?
686
            my $record_number;
647
        my $record_number = $result->{'biblionumber'};
687
            my $result = C4::Biblio::TransformMarcToKoha(C4::Context->dbh, $target_record, '');
648
        push @results, { 'record_id' => $record_number, 'score' => $matches{$marcblob} };
688
            $record_number = $result->{'biblionumber'};
689
            push @results, { 'record_id' => $record_number, 'score' => $matches{$marcblob} };
690
        }
691
    } elsif ($self->{'record_type'} eq 'authority') {
692
        require C4::AuthoritiesMarc;
693
        foreach my $authid (keys %matches) {
694
            push @results, { 'record_id' => $authid, 'score' => $matches{$authid} };
695
        }
649
    }
696
    }
650
    @results = sort { $b->{'score'} cmp $a->{'score'} } @results;
697
    @results = sort { $b->{'score'} cmp $a->{'score'} } @results;
651
    if (scalar(@results) > $max_matches) {
698
    if (scalar(@results) > $max_matches) {
Lines 673-678 sub dump { Link Here
673
    $result->{'matcher_id'} = $self->{'id'};
720
    $result->{'matcher_id'} = $self->{'id'};
674
    $result->{'code'} = $self->{'code'};
721
    $result->{'code'} = $self->{'code'};
675
    $result->{'description'} = $self->{'description'};
722
    $result->{'description'} = $self->{'description'};
723
    $result->{'record_type'} = $self->{'record_type'};
676
724
677
    $result->{'matchpoints'} = [];
725
    $result->{'matchpoints'} = [];
678
    foreach my $matchpoint (@{ $self->{'matchpoints'} }) {
726
    foreach my $matchpoint (@{ $self->{'matchpoints'} }) {
(-)a/acqui/addorderiso2709.pl (-3 / +3 lines)
Lines 156-162 if ($op eq ""){ Link Here
156
156
157
    # retrieve the file you want to import
157
    # retrieve the file you want to import
158
    my $import_batch_id = $cgiparams->{'import_batch_id'};
158
    my $import_batch_id = $cgiparams->{'import_batch_id'};
159
    my $biblios = GetImportBibliosRange($import_batch_id);
159
    my $biblios = GetImportRecordsRange($import_batch_id);
160
    for my $biblio (@$biblios){
160
    for my $biblio (@$biblios){
161
        # 1st insert the biblio, or find it through matcher
161
        # 1st insert the biblio, or find it through matcher
162
        my ( $marcblob, $encoding ) = GetImportRecordMarc( $biblio->{'import_record_id'} );
162
        my ( $marcblob, $encoding ) = GetImportRecordMarc( $biblio->{'import_record_id'} );
Lines 338-344 sub import_batches_list { Link Here
338
    foreach my $batch (@$batches) {
338
    foreach my $batch (@$batches) {
339
        if ($batch->{'import_status'} eq "staged") {
339
        if ($batch->{'import_status'} eq "staged") {
340
            # check if there is at least 1 line still staged
340
            # check if there is at least 1 line still staged
341
            my $stagedList=GetImportBibliosRange($batch->{'import_batch_id'}, undef, undef, 'staged');
341
            my $stagedList=GetImportRecordsRange($batch->{'import_batch_id'}, undef, undef, 'staged');
342
            if (scalar @$stagedList) {
342
            if (scalar @$stagedList) {
343
                my ($staged_date, $staged_hour) = split (/ /, $batch->{'upload_timestamp'});
343
                my ($staged_date, $staged_hour) = split (/ /, $batch->{'upload_timestamp'});
344
                push @list, {
344
                push @list, {
Lines 365-371 sub import_batches_list { Link Here
365
sub import_biblios_list {
365
sub import_biblios_list {
366
    my ($template, $import_batch_id) = @_;
366
    my ($template, $import_batch_id) = @_;
367
    my $batch = GetImportBatch($import_batch_id,'staged');
367
    my $batch = GetImportBatch($import_batch_id,'staged');
368
    my $biblios = GetImportBibliosRange($import_batch_id,'','','staged');
368
    my $biblios = GetImportRecordsRange($import_batch_id,'','','staged');
369
    my @list = ();
369
    my @list = ();
370
370
371
    foreach my $biblio (@$biblios) {
371
    foreach my $biblio (@$biblios) {
(-)a/admin/matching-rules.pl (-5 / +7 lines)
Lines 92-100 sub add_matching_rule_form { Link Here
92
sub add_update_matching_rule {
92
sub add_update_matching_rule {
93
    my $template = shift;
93
    my $template = shift;
94
    my $matcher_id = shift;
94
    my $matcher_id = shift;
95
    my $record_type = $input->param('record_type') || 'biblio';
95
96
96
    # do parsing
97
    # do parsing
97
    my $matcher = C4::Matcher->new('biblio', 1000); # FIXME biblio only for now
98
    my $matcher = C4::Matcher->new($record_type, 1000);
98
    $matcher->code($input->param('code'));
99
    $matcher->code($input->param('code'));
99
    $matcher->description($input->param('description'));
100
    $matcher->description($input->param('description'));
100
    $matcher->threshold($input->param('threshold'));
101
    $matcher->threshold($input->param('threshold'));
Lines 203-212 sub edit_matching_rule_form { Link Here
203
204
204
    my $matcher = C4::Matcher->fetch($matcher_id);
205
    my $matcher = C4::Matcher->fetch($matcher_id);
205
206
206
    $template->param(matcher_id => $matcher_id);
207
    $template->{VARS}->{'matcher_id'} = $matcher_id;
207
    $template->param(code => $matcher->code());
208
    $template->{VARS}->{'code'} = $matcher->code();
208
    $template->param(description => $matcher->description());
209
    $template->{VARS}->{'description'} = $matcher->description();
209
    $template->param(threshold => $matcher->threshold());
210
    $template->{VARS}->{'threshold'} = $matcher->threshold();
211
    $template->{VARS}->{'record_type'} = $matcher->record_type();
210
212
211
    my $matcher_info = $matcher->dump();
213
    my $matcher_info = $matcher->dump();
212
    my @matchpoints = ();
214
    my @matchpoints = ();
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/matching-rules.tt (+11 lines)
Lines 220-225 function CheckRuleForm(f) { Link Here
220
           <input type="text" id="threshold" name="threshold" size="5" maxlength="5" 
220
           <input type="text" id="threshold" name="threshold" size="5" maxlength="5" 
221
                  value="[% threshold |html %]" /> <span class="required">Required</span>
221
                  value="[% threshold |html %]" /> <span class="required">Required</span>
222
       </li>
222
       </li>
223
       <li><label for="record_type" class="required">Record type: </label>
224
           <select id="record_type" name="record_type">
225
               [% IF ( record_type == "authority" ) %]
226
                   <option value="biblio">Bibliographic record</option>
227
                   <option value="authority" selected="selected">Authority record</option>
228
               [% ELSE %]
229
                   <option value="biblio" selected="selected">Bibliographic record</option>
230
                   <option value="authority">Authority record</option>
231
               [% END %]
232
           </select><span class="required">Required</span>
233
       </li>
223
    </ol>
234
    </ol>
224
  </fieldset>
235
  </fieldset>
225
236
(-)a/misc/cronjobs/import_webservice_batch.pl (-1 / +1 lines)
Lines 54-57 EOF Link Here
54
my $batch_ids = GetStagedWebserviceBatches() or exit;
54
my $batch_ids = GetStagedWebserviceBatches() or exit;
55
55
56
$framework ||= '';
56
$framework ||= '';
57
BatchCommitBibRecords($_, $framework) foreach @$batch_ids;
57
BatchCommitRecords($_, $framework) foreach @$batch_ids;
(-)a/svc/import_bib (-1 / +1 lines)
Lines 92-98 sub import_bib { Link Here
92
    $marcxml =~ s/<\?xml.*?\?>//i;
92
    $marcxml =~ s/<\?xml.*?\?>//i;
93
93
94
    # XXX we are ignoring the result of this;
94
    # XXX we are ignoring the result of this;
95
    BatchCommitBibRecords($batch_id, $framework) if lc($import_mode) eq 'direct';
95
    BatchCommitRecords($batch_id, $framework) if lc($import_mode) eq 'direct';
96
96
97
    $result->{'status'} = "ok";
97
    $result->{'status'} = "ok";
98
    $result->{'import_batch_id'} =  $batch_id;
98
    $result->{'import_batch_id'} =  $batch_id;
(-)a/tools/manage-marc-import.pl (-41 / +46 lines)
Lines 99-105 if ($op eq "") { Link Here
99
    if ($import_batch_id eq '') {
99
    if ($import_batch_id eq '') {
100
        import_batches_list($template, $offset, $results_per_page);
100
        import_batches_list($template, $offset, $results_per_page);
101
    } else {
101
    } else {
102
        import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
102
        import_records_list($template, $import_batch_id, $offset, $results_per_page);
103
    }
103
    }
104
} elsif ($op eq "commit-batch") {
104
} elsif ($op eq "commit-batch") {
105
    if ($completedJobID) {
105
    if ($completedJobID) {
Lines 108-121 if ($op eq "") { Link Here
108
        my $framework = $input->param('framework');
108
        my $framework = $input->param('framework');
109
        commit_batch($template, $import_batch_id, $framework);
109
        commit_batch($template, $import_batch_id, $framework);
110
    }
110
    }
111
    import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
111
    import_records_list($template, $import_batch_id, $offset, $results_per_page);
112
} elsif ($op eq "revert-batch") {
112
} elsif ($op eq "revert-batch") {
113
    if ($completedJobID) {
113
    if ($completedJobID) {
114
        add_saved_job_results_to_template($template, $completedJobID);
114
        add_saved_job_results_to_template($template, $completedJobID);
115
    } else {
115
    } else {
116
        revert_batch($template, $import_batch_id);
116
        revert_batch($template, $import_batch_id);
117
    }
117
    }
118
    import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
118
    import_records_list($template, $import_batch_id, $offset, $results_per_page);
119
} elsif ($op eq "clean-batch") {
119
} elsif ($op eq "clean-batch") {
120
    CleanBatch($import_batch_id);
120
    CleanBatch($import_batch_id);
121
    import_batches_list($template, $offset, $results_per_page);
121
    import_batches_list($template, $offset, $results_per_page);
Lines 131-137 if ($op eq "") { Link Here
131
    my $item_action = $input->param('item_action');
131
    my $item_action = $input->param('item_action');
132
    redo_matching($template, $import_batch_id, $new_matcher_id, $current_matcher_id, 
132
    redo_matching($template, $import_batch_id, $new_matcher_id, $current_matcher_id, 
133
                  $overlay_action, $nomatch_action, $item_action);
133
                  $overlay_action, $nomatch_action, $item_action);
134
    import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
134
    import_records_list($template, $import_batch_id, $offset, $results_per_page);
135
} 
135
} 
136
136
137
output_html_with_http_headers $input, $cookie, $template->output;
137
output_html_with_http_headers $input, $cookie, $template->output;
Lines 163-183 sub redo_matching { Link Here
163
        $template->param('changed_item_action' => 1);
163
        $template->param('changed_item_action' => 1);
164
    }
164
    }
165
165
166
    if ($new_matcher_id eq $current_matcher_id) {
167
        return;
168
    } 
169
170
    my $num_with_matches = 0;
166
    my $num_with_matches = 0;
171
    if (defined $new_matcher_id and $new_matcher_id ne "") {
167
    if (defined $new_matcher_id and $new_matcher_id ne "") {
172
        my $matcher = C4::Matcher->fetch($new_matcher_id);
168
        my $matcher = C4::Matcher->fetch($new_matcher_id);
173
        if (defined $matcher) {
169
        if (defined $matcher) {
174
            $num_with_matches = BatchFindBibDuplicates($import_batch_id, $matcher);
170
            $num_with_matches = BatchFindDuplicates($import_batch_id, $matcher);
175
            SetImportBatchMatcher($import_batch_id, $new_matcher_id);
171
            SetImportBatchMatcher($import_batch_id, $new_matcher_id);
176
        } else {
172
        } else {
177
            $rematch_failed = 1;
173
            $rematch_failed = 1;
178
        }
174
        }
179
    } else {
175
    } else {
180
        $num_with_matches = BatchFindBibDuplicates($import_batch_id, undef);
176
        $num_with_matches = BatchFindDuplicates($import_batch_id, undef);
181
        SetImportBatchMatcher($import_batch_id, undef);
177
        SetImportBatchMatcher($import_batch_id, undef);
182
        SetImportBatchOverlayAction('create_new');
178
        SetImportBatchOverlayAction('create_new');
183
    }
179
    }
Lines 214-226 sub import_batches_list { Link Here
214
    foreach my $batch (@$batches) {
210
    foreach my $batch (@$batches) {
215
        push @list, {
211
        push @list, {
216
            import_batch_id => $batch->{'import_batch_id'},
212
            import_batch_id => $batch->{'import_batch_id'},
217
            num_biblios => $batch->{'num_biblios'},
213
            num_records => $batch->{'num_records'},
218
            num_items => $batch->{'num_items'},
214
            num_items => $batch->{'num_items'},
219
            upload_timestamp => $batch->{'upload_timestamp'},
215
            upload_timestamp => $batch->{'upload_timestamp'},
220
            import_status => $batch->{'import_status'},
216
            import_status => $batch->{'import_status'},
221
            file_name => $batch->{'file_name'} || "($batch->{'batch_type'})",
217
            file_name => $batch->{'file_name'} || "($batch->{'batch_type'})",
222
            comments => $batch->{'comments'},
218
            comments => $batch->{'comments'},
223
            can_clean => ($batch->{'import_status'} ne 'cleaned') ? 1 : 0,
219
            can_clean => ($batch->{'import_status'} ne 'cleaned') ? 1 : 0,
220
            record_type => $batch->{'record_type'},
224
        };
221
        };
225
    }
222
    }
226
    $template->param(batch_list => \@list); 
223
    $template->param(batch_list => \@list); 
Lines 244-250 sub commit_batch { Link Here
244
        $callback = progress_callback($job, $dbh);
241
        $callback = progress_callback($job, $dbh);
245
    }
242
    }
246
    my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) = 
243
    my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) = 
247
        BatchCommitBibRecords($import_batch_id, $framework, 50, $callback);
244
        BatchCommitRecords($import_batch_id, $framework, 50, $callback);
248
    $dbh->commit();
245
    $dbh->commit();
249
246
250
    my $results = {
247
    my $results = {
Lines 273-279 sub revert_batch { Link Here
273
        $callback = progress_callback($job, $dbh);
270
        $callback = progress_callback($job, $dbh);
274
    }
271
    }
275
    my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored) = 
272
    my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored) = 
276
        BatchRevertBibRecords($import_batch_id, 50, $callback);
273
        BatchRevertRecords($import_batch_id, 50, $callback);
277
    $dbh->commit();
274
    $dbh->commit();
278
275
279
    my $results = {
276
    my $results = {
Lines 295-301 sub put_in_background { Link Here
295
    my $import_batch_id = shift;
292
    my $import_batch_id = shift;
296
293
297
    my $batch = GetImportBatch($import_batch_id);
294
    my $batch = GetImportBatch($import_batch_id);
298
    my $job = C4::BackgroundJob->new($sessionID, $batch->{'file_name'}, $ENV{'SCRIPT_NAME'}, $batch->{'num_biblios'});
295
    my $job = C4::BackgroundJob->new($sessionID, $batch->{'file_name'}, $ENV{'SCRIPT_NAME'}, $batch->{'num_records'});
299
    my $jobID = $job->id();
296
    my $jobID = $job->id();
300
297
301
    # fork off
298
    # fork off
Lines 350-395 sub add_saved_job_results_to_template { Link Here
350
    add_results_to_template($template, $results);
347
    add_results_to_template($template, $results);
351
}
348
}
352
349
353
sub import_biblios_list {
350
sub import_records_list {
354
    my ($template, $import_batch_id, $offset, $results_per_page) = @_;
351
    my ($template, $import_batch_id, $offset, $results_per_page) = @_;
355
352
356
    my $batch = GetImportBatch($import_batch_id);
353
    my $batch = GetImportBatch($import_batch_id);
357
    my $biblios = GetImportBibliosRange($import_batch_id, $offset, $results_per_page);
354
    my $records = GetImportRecordsRange($import_batch_id, $offset, $results_per_page);
358
    my @list = ();
355
    my @list = ();
359
    foreach my $biblio (@$biblios) {
356
    foreach my $record (@$records) {
360
        my $citation = $biblio->{'title'};
357
        my $citation = $record->{'title'} || $record->{'authorized_heading'};
361
        $citation .= " $biblio->{'author'}" if $biblio->{'author'};
358
        $citation .= " $record->{'author'}" if $record->{'author'};
362
        $citation .= " (" if $biblio->{'issn'} or $biblio->{'isbn'};
359
        $citation .= " (" if $record->{'issn'} or $record->{'isbn'};
363
        $citation .= $biblio->{'isbn'} if $biblio->{'isbn'};
360
        $citation .= $record->{'isbn'} if $record->{'isbn'};
364
        $citation .= ", " if $biblio->{'issn'} and $biblio->{'isbn'};
361
        $citation .= ", " if $record->{'issn'} and $record->{'isbn'};
365
        $citation .= $biblio->{'issn'} if $biblio->{'issn'};
362
        $citation .= $record->{'issn'} if $record->{'issn'};
366
        $citation .= ")" if $biblio->{'issn'} or $biblio->{'isbn'};
363
        $citation .= ")" if $record->{'issn'} or $record->{'isbn'};
367
364
368
        my $match = GetImportRecordMatches($biblio->{'import_record_id'}, 1);
365
        my $match = GetImportRecordMatches($record->{'import_record_id'}, 1);
369
        my $match_citation = '';
366
        my $match_citation = '';
370
        if ($#$match > -1) {
367
        if ($#$match > -1) {
371
            $match_citation .= $match->[0]->{'title'} if defined($match->[0]->{'title'});
368
            if ($match->[0]->{'record_type'} eq 'biblio') {
372
            $match_citation .= ' ' . $match->[0]->{'author'} if defined($match->[0]->{'author'});
369
                $match_citation .= $match->[0]->{'title'} if defined($match->[0]->{'title'});
370
                $match_citation .= ' ' . $match->[0]->{'author'} if defined($match->[0]->{'author'});
371
            } elsif ($match->[0]->{'record_type'} eq 'auth') {
372
                $match_citation .= $match->[0]->{'authorized_heading'} if defined($match->[0]->{'authorized_heading'});
373
            }
373
        }
374
        }
374
375
375
        push @list,
376
        push @list,
376
          { import_record_id         => $biblio->{'import_record_id'},
377
          { import_record_id         => $record->{'import_record_id'},
377
            final_match_biblionumber => $biblio->{'matched_biblionumber'},
378
            final_match_id           => $record->{'matched_biblionumber'} || $record->{'matched_authid'},
378
            citation                 => $citation,
379
            citation                 => $citation,
379
            status                   => $biblio->{'status'},
380
            status                   => $record->{'status'},
380
            record_sequence          => $biblio->{'record_sequence'},
381
            record_sequence          => $record->{'record_sequence'},
381
            overlay_status           => $biblio->{'overlay_status'},
382
            overlay_status           => $record->{'overlay_status'},
382
            match_biblionumber       => $#$match > -1 ? $match->[0]->{'biblionumber'} : 0,
383
            # Sorry about the match_id being from the "biblionumber" field;
384
            # as it turns out, any match id will go in biblionumber
385
            match_id                 => $#$match > -1 ? $match->[0]->{'biblionumber'} : 0,
383
            match_citation           => $match_citation,
386
            match_citation           => $match_citation,
384
            match_score              => $#$match > -1 ? $match->[0]->{'score'} : 0,
387
            match_score              => $#$match > -1 ? $match->[0]->{'score'} : 0,
388
            record_type              => $record->{'record_type'},
385
          };
389
          };
386
    }
390
    }
387
    my $num_biblios = $batch->{'num_biblios'};
391
    my $num_records = $batch->{'num_records'};
388
    $template->param(biblio_list => \@list); 
392
    $template->param(record_list => \@list);
389
    add_page_numbers($template, $offset, $results_per_page, $num_biblios);
393
    add_page_numbers($template, $offset, $results_per_page, $num_records);
390
    $template->param(offset => $offset);
394
    $template->param(offset => $offset);
391
    $template->param(range_top => $offset + $results_per_page - 1);
395
    $template->param(range_top => $offset + $results_per_page - 1);
392
    $template->param(num_results => $num_biblios);
396
    $template->param(num_results => $num_records);
393
    $template->param(results_per_page => $results_per_page);
397
    $template->param(results_per_page => $results_per_page);
394
    $template->param(import_batch_id => $import_batch_id);
398
    $template->param(import_batch_id => $import_batch_id);
395
    my $overlay_action = GetImportBatchOverlayAction($import_batch_id);
399
    my $overlay_action = GetImportBatchOverlayAction($import_batch_id);
Lines 412-423 sub batch_info { Link Here
412
    $template->param(comments => $batch->{'comments'});
416
    $template->param(comments => $batch->{'comments'});
413
    $template->param(import_status => $batch->{'import_status'});
417
    $template->param(import_status => $batch->{'import_status'});
414
    $template->param(upload_timestamp => $batch->{'upload_timestamp'});
418
    $template->param(upload_timestamp => $batch->{'upload_timestamp'});
415
    $template->param(num_biblios => $batch->{'num_biblios'});
419
    $template->{VARS}->{'record_type'} = $batch->{'record_type'};
416
    $template->param(num_items => $batch->{'num_biblios'});
420
    $template->param(num_records => $batch->{'num_records'});
421
    $template->param(num_items => $batch->{'num_items'});
417
    if ($batch->{'import_status'} ne 'cleaned') {
422
    if ($batch->{'import_status'} ne 'cleaned') {
418
        $template->param(can_clean => 1);
423
        $template->param(can_clean => 1);
419
    }
424
    }
420
    if ($batch->{'num_biblios'} > 0) {
425
    if ($batch->{'num_records'} > 0) {
421
        if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') {
426
        if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') {
422
            $template->param(can_commit => 1);
427
            $template->param(can_commit => 1);
423
        }
428
        }
(-)a/tools/stage-marc-import.pl (-3 / +2 lines)
Lines 130-136 if ($completedJobID) { Link Here
130
    }
130
    }
131
131
132
    # FIXME branch code
132
    # FIXME branch code
133
    my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($encoding, $marcrecord, $filename, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh));
133
    my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStageMarcRecords($record_type, $encoding, $marcrecord, $filename, $comments, '', $parse_items, 0, 50, staging_progress_callback($job, $dbh));
134
134
135
    $dbh->commit();
135
    $dbh->commit();
136
136
Lines 143-149 if ($completedJobID) { Link Here
143
        if (defined $matcher) {
143
        if (defined $matcher) {
144
            $checked_matches = 1;
144
            $checked_matches = 1;
145
            $matcher_code = $matcher->code();
145
            $matcher_code = $matcher->code();
146
            $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher, 
146
            $num_with_matches = BatchFindDuplicates($batch_id, $matcher,
147
                                                       10, 50, matching_progress_callback($job, $dbh));
147
                                                       10, 50, matching_progress_callback($job, $dbh));
148
            SetImportBatchMatcher($batch_id, $matcher_id);
148
            SetImportBatchMatcher($batch_id, $matcher_id);
149
            SetImportBatchOverlayAction($batch_id, $overlay_action);
149
            SetImportBatchOverlayAction($batch_id, $overlay_action);
150
- 

Return to bug 2060