Browse Source

batch import rework -- implement stage-commit-undo for batch import

Revamps the import options on the tools menu to have two parts:

[1] Staging (load file into reservoir)
[2] Managing (review the list of staged batches, then
    choose to commit or undo a given batch.

Signed-off-by: Chris Cormack <crc@liblime.com>
Signed-off-by: Joshua Ferraro <jmf@liblime.com>
3.0.x
Galen Charlton 17 years ago
committed by Joshua Ferraro
parent
commit
853aa657ba
  1. 1
      C4/Breeding.pm
  2. 301
      C4/ImportBatch.pm
  3. 8
      koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc
  4. 0
      koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/stage-marc-import.tmpl
  5. 74
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/import.tmpl
  6. 180
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tmpl
  7. 76
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl
  8. 7
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tmpl
  9. 196
      tools/manage-marc-import.pl
  10. 70
      tools/stage-marc-import.pl

1
C4/Breeding.pm

@ -80,7 +80,6 @@ sub ImportBreeding {
$batch_id = GetZ3950BatchId($filename);
} else {
# create a new one
# FIXME - handle comments
$batch_id = AddImportBatch('create_new', 'staging', 'batch', $filename, '');
}
my $searchisbn = $dbh->prepare("select biblioitemnumber from biblioitems where isbn=?");

301
C4/ImportBatch.pm

@ -51,12 +51,18 @@ use C4::ImportBatch;
GetZ3950BatchId
GetImportRecordMarc
AddImportBatch
GetImportBatch
AddBiblioToBatch
ModBiblioInBatch
BatchStageMarcRecords
BatchFindBibDuplicates
BatchCommitBibRecords
BatchRevertBibRecords
GetImportBatchRangeDesc
GetNumberOfNonZ3950ImportBatches
GetImportBibliosRange
GetImportBatchStatus
SetImportBatchStatus
@ -64,6 +70,9 @@ use C4::ImportBatch;
SetImportBatchOverlayAction
GetImportRecordOverlayStatus
SetImportRecordOverlayStatus
GetImportRecordStatus
SetImportRecordStatus
GetImportRecordMatches
SetImportRecordMatches
);
@ -147,21 +156,52 @@ sub AddImportBatch {
}
=head2 GetImportBatch
=over 4
my $row = GetImportBatch($batch_id);
=back
Retrieve a hashref of an import_batches row.
=cut
sub GetImportBatch {
my ($batch_id) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
$sth->bind_param(1, $batch_id);
$sth->execute();
my $result = $sth->fetchrow_hashref;
$sth->finish();
return $result;
}
=head2 AddBiblioToBatch
=over 4
my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence, $marc_record, $encoding, $z3950random);
my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence, $marc_record, $encoding, $z3950random, $update_counts);
=back
=cut
sub AddBiblioToBatch {
my ($batch_id, $record_sequence, $marc_record, $encoding, $z3950random) = @_;
my $batch_id = shift;
my $record_sequence = shift;
my $marc_record = shift;
my $encoding = shift;
my $z3950random = shift;
my $update_counts = @_ ? shift : 1;
my $import_record_id = _create_import_record($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random);
_add_biblio_fields($import_record_id, $marc_record);
_update_batch_record_counts($batch_id) if $update_counts;
return $import_record_id;
}
@ -210,13 +250,14 @@ sub BatchStageMarcRecords {
push @invalid_records, $marc_blob;
} else {
$num_valid++;
$import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $marc_flavor, int(rand(99999)));
$import_record_id = AddBiblioToBatch($batch_id, $rec_num, $marc_record, $marc_flavor, int(rand(99999)), 0);
}
}
unless ($leave_as_staging) {
SetImportBatchStatus($batch_id, 'staged');
}
# FIXME batch_code, number of bibs, number of items
# FIXME branch_code, number of bibs, number of items
_update_batch_record_counts($batch_id);
return ($batch_id, $num_valid, @invalid_records);
}
@ -305,24 +346,175 @@ sub BatchCommitBibRecords {
($overlay_action eq 'replace' and $rowref->{'overlay_status'} eq 'no_match')) {
$num_added++;
my ($biblionumber, $biblioitemnumber) = AddBiblio($marc_record, '');
my $sth = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
$sth->execute($biblionumber, $rowref->{'import_record_id'});
$sth->finish();
SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
} else {
$num_updated++;
my $biblionumber = GetBestRecordMatch($rowref->{'import_record_id'});
my ($count, $oldbiblio) = GetBiblio($biblionumber);
my $oldxml = GetXmlBiblio($biblionumber);
ModBiblio($marc_record, $biblionumber, $oldbiblio->{'frameworkcode'});
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
$sth->execute($oldxml, $rowref->{'import_record_id'});
$sth->finish();
my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
$sth2->execute($biblionumber, $rowref->{'import_record_id'});
$sth2->finish();
SetImportRecordOverlayStatus($rowref->{'import_record_id'}, 'match_applied');
SetImportRecordStatus($rowref->{'import_record_id'}, 'imported');
}
}
$sth->finish();
SetImportBatchStatus('imported');
SetImportBatchStatus($batch_id, 'imported');
return ($num_added, $num_updated, $num_ignored);
}
=head2 BatchRevertBibRecords
=over 4
my ($num_deleted, $num_errors, $num_reverted, $num_ignored) = BatchRevertBibRecords($batch_id);
=back
=cut
sub BatchRevertBibRecords {
my $batch_id = shift;
my $num_deleted = 0;
my $num_errors = 0;
my $num_reverted = 0;
my $num_ignored = 0;
# commit (i.e., save, all records in the batch)
# FIXME biblio only at the moment
SetImportBatchStatus('reverting');
my $overlay_action = GetImportBatchOverlayAction($batch_id);
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marcxml_old, encoding, matched_biblionumber
FROM import_records
JOIN import_biblios USING (import_record_id)
WHERE import_batch_id = ?");
$sth->execute($batch_id);
while (my $rowref = $sth->fetchrow_hashref) {
if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
$num_ignored++;
}
if ($overlay_action eq 'create_new' or
($overlay_action eq 'replace' and $rowref->{'overlay_status'} eq 'no_match')) {
my $error = DelBiblio($rowref->{'matched_biblionumber'});
if (defined $error) {
$num_errors++;
} else {
$num_deleted++;
SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
}
} else {
$num_reverted++;
my $old_record = MARC::Record->new_from_xml($rowref->{'marcxml_old'}, 'UTF-8', $rowref->{'encoding'});
my $biblionumber = $rowref->{'matched_biblionumber'};
my ($count, $oldbiblio) = GetBiblio($biblionumber);
ModBiblio($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
SetImportRecordStatus($rowref->{'import_record_id'}, 'reverted');
}
}
$sth->finish();
SetImportBatchStatus($batch_id, 'reverted');
return ($num_deleted, $num_errors, $num_reverted, $num_ignored);
}
=head2 GetImportBatchRangeDesc
=over 4
my $results = GetImportBatchRangeDesc($offset, $results_per_group);
=back
Returns a reference to an array of hash references corresponding to
import_batches rows (sorted in descending order by import_batch_id)
start at the given offset.
=cut
sub GetImportBatchRangeDesc {
my ($offset, $results_per_group) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
WHERE batch_type = 'batch'
ORDER BY import_batch_id DESC
LIMIT ? OFFSET ?");
$sth->bind_param(1, $results_per_group);
$sth->bind_param(2, $offset);
my $results = [];
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
push @$results, $row;
}
$sth->finish();
return $results;
}
=head2 GetNumberOfImportBatches
=over 4
my $count = GetNumberOfImportBatches();
=back
=cut
sub GetNumberOfNonZ3950ImportBatches {
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type='batch'");
$sth->execute();
my ($count) = $sth->fetchrow_array();
$sth->finish();
return $count;
}
=head2 GetImportBibliosRange
=over 4
my $results = GetImportBibliosRange($batch_id, $offset, $results_per_group);
=back
Returns a reference to an array of hash references corresponding to
import_biblios/import_records rows for a given batch
starting at the given offset.
=cut
sub GetImportBibliosRange {
my ($batch_id, $offset, $results_per_group) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare_cached("SELECT title, author, isbn, issn, import_record_id, record_sequence,
status, overlay_status
FROM import_records
JOIN import_biblios USING (import_record_id)
WHERE import_batch_id = ?
ORDER BY import_record_id LIMIT ? OFFSET ?");
$sth->bind_param(1, $batch_id);
$sth->bind_param(2, $results_per_group);
$sth->bind_param(3, $offset);
my $results = [];
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
push @$results, $row;
}
$sth->finish();
return $results;
}
=head2 GetBestRecordMatch
=over 4
@ -476,6 +668,85 @@ sub SetImportRecordOverlayStatus {
}
=head2 GetImportRecordStatus
=over 4
my $overlay_status = GetImportRecordStatus($import_record_id);
=back
=cut
sub GetImportRecordStatus {
my ($import_record_id) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
$sth->execute($import_record_id);
my ($overlay_status) = $sth->fetchrow_array();
$sth->finish();
return $overlay_status;
}
=head2 SetImportRecordStatus
=over 4
SetImportRecordStatus($import_record_id, $new_overlay_status);
=back
=cut
sub SetImportRecordStatus {
my ($import_record_id, $new_overlay_status) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
$sth->execute($new_overlay_status, $import_record_id);
$sth->finish();
}
=head2 GetImportRecordMatches
=over 4
my $results = GetImportRecordMatches($import_record_id, $best_only);
=back
=cut
sub GetImportRecordMatches {
my $import_record_id = shift;
my $best_only = @_ ? shift : 0;
my $dbh = C4::Context->dbh;
# FIXME currently biblio only
my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber, score
FROM import_records
JOIN import_record_matches USING (import_record_id)
JOIN biblio ON (biblionumber = candidate_match_id)
WHERE import_record_id = ?
ORDER BY score DESC, biblionumber DESC");
$sth->bind_param(1, $import_record_id);
my $results = [];
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
push @$results, $row;
last if $best_only;
}
$sth->finish();
return $results;
}
=head2 SetImportRecordMatches
=over 4
@ -570,6 +841,22 @@ sub _parse_biblio_fields {
}
sub _update_batch_record_counts {
my ($batch_id) = @_;
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare_cached("UPDATE import_batches SET num_biblios = (
SELECT COUNT(*)
FROM import_records
WHERE import_batch_id = import_batches.import_batch_id
AND record_type = 'biblio')
WHERE import_batch_id = ?");
$sth->bind_param(1, $batch_id);
$sth->execute();
$sth->finish();
}
1;
=head1 AUTHOR

8
koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc

@ -1,10 +1,14 @@
<ul>
<li><a href="/cgi-bin/koha/tools/tools-home.pl">Tools Home</a></li>
<li><a href="/cgi-bin/koha/tools/koha-news.pl">News</a></li>
<li><a href="/cgi-bin/koha/labels/label-home.pl">Labels (spine and barcode)</a></li>
<li><a href="/cgi-bin/koha/tools/holidays.pl">Holidays</a></li>
<li><a href="/cgi-bin/koha/tools/inventory.pl">Inventory/stocktaking</a></li>
<li><a href="/cgi-bin/koha/tools/cleanborrowers.pl">Clean borrowers</a></li>
<li><a href="/cgi-bin/koha/tools/export.pl">Export</a></li>
<li><a href="/cgi-bin/koha/tools/stage-marc-import.pl">MARC Import (staging)</a></li>
<li><a href="/cgi-bin/koha/tools/manage-marc-import.pl">MARC Import (managing batches)</a></li>
<li><a href="/cgi-bin/koha/tools/letter.pl">Notices</a></li>
<li><a href="/cgi-bin/koha/tools/overduerules.pl">Notice/status triggers</a></li>
<li><a href="/cgi-bin/koha/labels/label-home.pl">Labels</a></li>
<li><a href="/cgi-bin/koha/tools/viewlog.pl">Log viewer</a></li>
<li><a href="/cgi-bin/koha/tools/inventory.pl">Inventory/stocktaking</a></li>
<li><a href="/cgi-bin/koha/tools/export.pl">Export bibs/holdings</a></li>

0
koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/import.tmpl → koha-tmpl/intranet-tmpl/prog/en/modules/help/tools/stage-marc-import.tmpl

74
koha-tmpl/intranet-tmpl/prog/en/modules/tools/import.tmpl

@ -1,74 +0,0 @@
<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
<title>Koha &rsaquo; Tools &rsaquo; MARC Import</title>
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
</head>
<body>
<!-- TMPL_INCLUDE NAME="header.inc" -->
<!-- TMPL_INCLUDE NAME="cat-search.inc" -->
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; MARC Import</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<h1>MARC acquisition system</h1>
<!-- TMPL_IF name="uploadmarc" -->
<p>Import results :</p>
<ul>
<li><!-- TMPL_VAR name="imported" --> imported records</li>
<li><!-- TMPL_VAR name="alreadyindb" --> not imported because already in catalog</li>
<li><!-- TMPL_VAR name="alreadyinfarm" --> not imported because already in the reservoir</li>
<li><!-- TMPL_VAR name="notmarcrecord" --> not imported because they seem not to be in MARC format (or ISBN/ISSN missing) !</li>
<li><!-- TMPL_VAR name="total" --> records parsed</li>
<li><a href="/cgi-bin/koha/tools/tools-home.pl">Back</a></li>
</ul>
<!-- TMPL_ELSE -->
<ul>
<li>Select a file to import into the reservoir. It will be parsed, and for each ISBN found, a new baby will be created in the reservoir.</li>
<li>If an ISBN already exists in the reservoir, you can choose whether to ignore the new one or overwrite the old one.</li>
<li>You can enter a name for this import. It may be useful, when creating a biblio, to remember where the suggested MARC data comes from!</li>
<li>Of course, if the ISBN already exists in the active DB, the biblio will be ignored.</li>
</ul>
<form method="post" action="<!-- TMPL_VAR name="SCRIPT_NAME" -->" enctype="multipart/form-data">
<fieldset class="rows">
<legend>Import into the reservoir</legend><ol>
<li>
<label for="uploadmarc">Select the file to import: </label>
<input type="file" id="uploadmarc" name="uploadmarc" /><br />
</li>
<li>
<label for="comments">Notes about this import: </label>
<input type="text" id="comments" name="comments" />
</li>
<li>
<label for="syntax">Character encoding: </label>
<select name="syntax" id="syntax"><option value="MARC21">MARC21</option><option value="UNIMARC">UNIMARC</option></select>
</li>
</ol></fieldset>
<fieldset class="rows">
<legend>If ISBN is already in the reservoir:</legend><ol><li class="radio">
<input type="radio" id="overwrite_bibliono" name="overwrite_biblio" value="0" checked="checked" /><label for="overwrite_bibliono">Ignore this one, keep the existing one</label></li>
<li class="radio">
<input type="radio" id="overwrite_biblioyes" name="overwrite_biblio" value="1" /><label for="overwrite_biblioyes">Overwrite the existing one with this</label>
</li></ol></fieldset><input type="submit" value="Import" />
</form>
<!-- /TMPL_IF -->
</div>
</div>
<div class="yui-b">
<!-- TMPL_INCLUDE NAME="tools-menu.inc" -->
</div>
</div>
<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->

180
koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tmpl

@ -0,0 +1,180 @@
<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
<title>Koha &rsaquo; Tools &rsaquo; Manage Staged MARC Records
<!-- TMPL_IF name="import_batch_id" -->
&rsaquo; Batch <!-- TMPL_VAR name="import_batch_id" -->
<!-- /TMPL_IF -->
</title>
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
</head>
<body>
<!-- TMPL_INCLUDE NAME="header.inc" -->
<!-- TMPL_INCLUDE NAME="cat-search.inc" -->
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a>
<!-- TMPL_IF name="import_batch_id" -->
&rsaquo;
<a href="<!-- TMPL_VAR name="script_name"-->">Manage Staged MARC Records</a>
&rsaquo; Batch <!-- TMPL_VAR name="import_batch_id" -->
<!-- TMPL_ELSE -->
&rsaquo; Manage Staged MARC Records
<!-- /TMPL_IF -->
</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<h1>Manage Staged MARC Records
<!-- TMPL_IF name="import_batch_id" -->
&rsaquo; Batch <!-- TMPL_VAR name="import_batch_id" -->
<!-- /TMPL_IF -->
</h1>
<!-- TMPL_IF name="batch_info" -->
<p><label>File name</label> <!-- TMPL_VAR name="file_name" --></p>
<p><label>Comments</label> <!-- TMPL_VAR name="comments" --></p>
<p><label>Staged</label> <!-- TMPL_VAR name="upload_timestamp" --></p>
<p><label>Status</label> <!-- TMPL_VAR name="import_status" --></p>
<p>
<!-- TMPL_IF name="can_commit" -->
<form action="<!-- TMPL_VAR name="script_name" -->" method="post">
<input type="hidden" name="op" value="commit-batch" />
<input type="hidden" name="import_batch_id" value="<!-- TMPL_VAR name="import_batch_id" -->" />
<input type="submit" class="button" value="Complete import" />
</form>
<!-- /TMPL_IF -->
<!-- TMPL_IF name="can_revert" -->
<form action="<!-- TMPL_VAR name="script_name" -->" method="post">
<input type="hidden" name="op" value="revert-batch" />
<input type="hidden" name="import_batch_id" value="<!-- TMPL_VAR name="import_batch_id" -->" />
<input type="submit" class="button" value="Undo import" />
</form>
<!-- /TMPL_IF -->
</p>
<!-- TMPL_IF name="did_commit" -->
<p><span class="problem">Completed import of records</span></p>
<table>
<tr><td>Number of records added</td><td><!-- TMPL_VAR name="num_added" --></td></tr>
<tr><td>Number of records updated</td><td><!-- TMPL_VAR name="num_updated" --></td></tr>
<tr><td>Number of records ignored</td><td><!-- TMPL_VAR name="num_ignored" --></td></tr>
</table>
<!-- /TMPL_IF -->
<!-- TMPL_IF name="did_revert" -->
<p><span class="problem">Undid import of records</span></p>
<table>
<tr><td>Number of records deleted</td><td><!-- TMPL_VAR name="num_deleted" --></td></tr>
<tr><td>Number of records not deleted due to items on loan</td><td><!-- TMPL_VAR name="num_errors" --></td></tr>
<tr><td>Number of records changed back</td><td><!-- TMPL_VAR name="num_reverted" --></td></tr>
<tr><td>Number of records ignored</td><td><!-- TMPL_VAR name="num_ignored" --></td></tr>
</table>
<!-- /TMPL_IF -->
<!-- /TMPL_IF -->
<br />
<!-- TMPL_IF name="batch_list" -->
<!-- TMPL_IF name="pages" -->
<div class="pages">
Page
<!-- TMPL_LOOP name="pages" -->
<!-- TMPL_IF name="current_page" -->
<span class="current"><!-- TMPL_VAR name="page_number" --></span>
<!-- TMPL_ELSE -->
<a class="nav" href="<!-- TMPL_VAR name="script_name" -->?offset=<!-- TMPL_VAR name="offset" -->"><!-- TMPL_VAR name="page_number" --></a>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</div>
<!-- /TMPL_IF -->
<table>
<tr>
<th>#</th>
<th>File name</th>
<th>Comments</th>
<th>Status</th>
<th>Staged</th>
<th># Bibs</th.
<th># Items</th>
</tr>
<!-- TMPL_LOOP name="batch_list" -->
<tr>
<td><a href="<!-- TMPL_VAR name="script_name" -->?import_batch_id=<!-- TMPL_VAR name="import_batch_id" -->"><!-- TMPL_VAR name="import_batch_id" --></a></td>
<td><!-- TMPL_VAR name="file_name" --></td>
<td><!-- TMPL_VAR name="comments" --></td>
<td><!-- TMPL_VAR name="import_status" --></td>
<td><!-- TMPL_VAR name="upload_timestamp" --></td>
<td><!-- TMPL_VAR name="num_biblios" --></td>
<td><!-- TMPL_VAR name="num_items" --></td>
</tr>
<!-- /TMPL_LOOP -->
</table>
<!-- TMPL_IF name="pages" -->
<div class="pages">
Page
<!-- TMPL_LOOP name="pages" -->
<!-- TMPL_IF name="current_page" -->
<span class="current"><!-- TMPL_VAR name="page_number" --></span>
<!-- TMPL_ELSE -->
<a class="nav" href="<!-- TMPL_VAR name="script_name" -->?offset=<!-- TMPL_VAR name="offset" -->"><!-- TMPL_VAR name="page_number" --></a>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</div>
<!-- /TMPL_IF -->
<!-- /TMPL_IF -->
<!-- TMPL_IF name="biblio_list" -->
<!-- TMPL_IF name="pages" -->
<div class="pages">
Page
<!-- TMPL_LOOP name="pages" -->
<!-- TMPL_IF name="current_page" -->
<span class="current"><!-- TMPL_VAR name="page_number" --></span>
<!-- TMPL_ELSE -->
<a class="nav" href="<!-- TMPL_VAR name="script_name" -->?import_batch_id=<!-- TMPL_VAR name="import_batch_id" -->&offset=<!-- TMPL_VAR name="offset" -->"><!-- TMPL_VAR name="page_number" --></a>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</div>
<!-- /TMPL_IF -->
<table>
<tr>
<th>#</th>
<th>Citation</th>
<th>Status</th>
<th>Overlay?</th>
</tr>
<!-- TMPL_LOOP name="biblio_list" -->
<tr>
<td><!-- TMPL_VAR name="record_sequence"--></td>
<td><!-- TMPL_VAR name="citation"--></td>
<td><!-- TMPL_VAR name="status"--></td>
<td><!-- TMPL_VAR name="overlay_status"--></td>
</tr>
<!-- TMPL_IF name="match_biblionumber" -->
<tr>
<td />
<td class="highlight" colspan="3">Matches biblio <!-- TMPL_VAR name="match_biblionumber" --> (score = <!-- TMPL_VAR name="match_score" -->): <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR name="match_biblionumber" -->"><!-- TMPL_VAR name="match_citation" --></a></td>
</tr>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</table>
<!-- TMPL_IF name="pages" -->
<div class="pages">
Page
<!-- TMPL_LOOP name="pages" -->
<!-- TMPL_IF name="current_page" -->
<span class="current"><!-- TMPL_VAR name="page_number" --></span>
<!-- TMPL_ELSE -->
<a class="nav" href="<!-- TMPL_VAR name="script_name" -->?import_batch_id=<!-- TMPL_VAR name="import_batch_id" -->&offset=<!-- TMPL_VAR name="offset" -->"><!-- TMPL_VAR name="page_number" --></a>
<!-- /TMPL_IF -->
<!-- /TMPL_LOOP -->
</div>
<!-- /TMPL_IF -->
<!-- /TMPL_IF -->
</div>
</div>
<div class="yui-b">
<!-- TMPL_INCLUDE NAME="tools-menu.inc" -->
</div>
</div>
<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->

76
koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl

@ -0,0 +1,76 @@
<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
<title>Koha &rsaquo; Tools &rsaquo; Stage MARC Records For Import</title>
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
</head>
<body>
<!-- TMPL_INCLUDE NAME="header.inc" -->
<!-- TMPL_INCLUDE NAME="cat-search.inc" -->
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; Stage MARC Records For Import</div>
<div id="doc3" class="yui-t2">
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<h1>Stage MARC Records For Import</h1>
<!-- TMPL_IF name="uploadmarc" -->
<p>MARC Staging results :</p>
<ul>
<li><!-- TMPL_VAR name="total" --> records in file</li>
<li><!-- TMPL_VAR name="import_errors" --> records not staged because of MARC error</li>
<li><!-- TMPL_VAR name="staged" --> records staged</li>
<!-- TMPL_IF name="checked_matches" -->
<li><!-- TMPL_VAR name="matched" --> records with at least one match in catalogue</li>
<!-- TMPL_ELSE -->
<li>Did not check for matches with existing records in catalogue</li>
<!-- /TMPL_IF -->
<li><a href="/cgi-bin/koha/tools/manage-marc-import.pl?import_batch_id=<!-- TMPL_VAR name="import_batch_id" -->">Manage staged records</a></li>
<li><a href="/cgi-bin/koha/tools/tools-home.pl">Back</a></li>
</ul>
<!-- TMPL_ELSE -->
<ul>
<li>Select a MARC file to stage in the import reservoir. It will be parsed, and each valid record staged for later import into the catalogue.</li>
<li>You can enter a name for this import. It may be useful, when creating a biblio, to remember where the suggested MARC data comes from!</li>
</ul>
<form method="post" action="<!-- TMPL_VAR name="SCRIPT_NAME" -->" enctype="multipart/form-data">
<fieldset class="rows">
<legend>Stage records into the reservoir</legend><ol>
<li>
<label for="uploadmarc">Select the file to stage: </label>
<input type="file" id="uploadmarc" name="uploadmarc" /><br />
</li>
<li>
<label for="comments">Notes about this file: </label>
<input type="text" id="comments" name="comments" />
</li>
<li>
<label for="syntax">Character encoding: </label>
<select name="syntax" id="syntax"><option value="MARC21">MARC21</option><option value="UNIMARC">UNIMARC</option></select>
</li>
</ol></fieldset>
<fieldset class="rows">
<legend>Look for existing records in catalogue?</legend><ol><li class="radio">
<input type="radio" id="check_for_matchesno" name="check_for_matches" value="0" checked="checked" /><label for="check_for_matchesno">Do not look for matching records (using ISBN)</label></li>
<li class="radio">
<input type="radio" id="check_for_matchesyes" name="check_for_matches" value="1" /><label for="check_for_matchesyes">Look for matching records</label>
</li></ol></fieldset><input type="submit" value="Import" />
</form>
<!-- /TMPL_IF -->
</div>
</div>
<div class="yui-b">
<!-- TMPL_INCLUDE NAME="tools-menu.inc" -->
</div>
</div>
<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" -->

7
koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tmpl

@ -37,7 +37,14 @@
<dt><a href="/cgi-bin/koha/tools/inventory.pl">Inventory/stocktaking</a></dt>
<dd>Perform inventory (stocktaking) of your catalogue</dd>
<dt><a href="/cgi-bin/koha/tools/import_borrowers.pl">Import Borrowers</a></dt>
<dd>Import borrowers data.</dd>
<dt><a href="/cgi-bin/koha/tools/stage-marc-import.pl">Stage MARC Records For Import</a></dt>
<dd>Stage MARC records into the reservoir.</dd>
<dt><a href="/cgi-bin/koha/tools/manage-marc-import.pl">Manage Staged MARC Records</a></dt>
<dd>Managed staged MARC records, including completing and reversing imports.</dd>
</dl>
</div>
<div class="yui-u">

196
tools/manage-marc-import.pl

@ -0,0 +1,196 @@
#!/usr/bin/perl
# Copyright (C) 2007 LibLime
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
use strict;
# standard or CPAN modules used
use CGI;
use MARC::File::USMARC;
# Koha modules used
use C4::Context;
use C4::Auth;
use C4::Input;
use C4::Output;
use C4::Biblio;
use C4::ImportBatch;
use C4::Matcher;
my $script_name = "/cgi-bin/koha/tools/manage-marc-import.pl";
my $input = new CGI;
my $op = $input->param('op');
my $import_batch_id = $input->param('import_batch_id');
# record list displays
my $offset = $input->param('offset') || 0;
my $results_per_page = $input->param('results_per_page') || 10;
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "tools/manage-marc-import.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
flagsrequired => {parameters => 1},
debug => 1,
});
if ($op) {
$template->param(script_name => $script_name, $op => 1);
} else {
$template->param(script_name => $script_name);
}
if ($op eq "") {
# displaying a list
if ($import_batch_id eq "") {
import_batches_list($template, $offset, $results_per_page);
} else {
import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
}
} elsif ($op eq "commit-batch") {
commit_batch($template, $import_batch_id);
import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
} elsif ($op eq "revert-batch") {
revert_batch($template, $import_batch_id);
import_biblios_list($template, $import_batch_id, $offset, $results_per_page);
} elsif ($op eq "clean-batch") {
;
}
output_html_with_http_headers $input, $cookie, $template->output;
exit 0;
sub import_batches_list {
my ($template, $offset, $results_per_page) = @_;
my $batches = GetImportBatchRangeDesc($offset, $results_per_page);
my @list = ();
foreach my $batch (@$batches) {
push @list, {
import_batch_id => $batch->{'import_batch_id'},
num_biblios => $batch->{'num_biblios'},
num_items => $batch->{'num_items'},
upload_timestamp => $batch->{'upload_timestamp'},
import_status => $batch->{'import_status'},
file_name => $batch->{'file_name'},
comments => $batch->{'comments'}
};
}
$template->param(batch_list => \@list);
my $num_batches = GetNumberOfNonZ3950ImportBatches();
add_page_numbers($template, $offset, $results_per_page, $num_batches);
$template->param(offset => $offset);
$template->param(range_top => $offset + $results_per_page - 1);
$template->param(num_results => $num_batches);
$template->param(results_per_page => $results_per_page);
}
sub commit_batch {
my ($template, $import_batch_id) = @_;
my ($num_added, $num_updated, $num_ignored) = BatchCommitBibRecords($import_batch_id);
$template->param(did_commit => 1);
$template->param(num_added => $num_added);
$template->param(num_updated => $num_updated);
$template->param(num_ignored => $num_ignored);
}
sub revert_batch {
my ($template, $import_batch_id) = @_;
my ($num_deleted, $num_errors, $num_reverted, $num_ignored) = BatchRevertBibRecords($import_batch_id);
$template->param(did_revert => 1);
$template->param(num_deleted => $num_deleted);
$template->param(num_errors => $num_errors);
$template->param(num_reverted => $num_reverted);
$template->param(num_ignored => $num_ignored);
}
sub import_biblios_list {
my ($template, $import_batch_id, $offset, $results_per_page) = @_;
my $batch = GetImportBatch($import_batch_id);
my $biblios = GetImportBibliosRange($import_batch_id, $offset, $results_per_page);
my @list = ();
foreach my $biblio (@$biblios) {
my $citation = $biblio->{'title'};
$citation .= " $biblio->{'author'}" if $biblio->{'author'};
$citation .= " (" if $biblio->{'issn'} or $biblio->{'isbn'};
$citation .= $biblio->{'isbn'} if $biblio->{'isbn'};
$citation .= ", " if $biblio->{'issn'} and $biblio->{'isbn'};
$citation .= $biblio->{'issn'} if $biblio->{'issn'};
$citation .= ")" if $biblio->{'issn'} or $biblio->{'isbn'};
my $match = GetImportRecordMatches($biblio->{'import_record_id'}, 1);
push @list, {
import_record_id => $biblio->{'import_record_id'},
citation => $citation,
status => $biblio->{'status'},
record_sequence => $biblio->{'record_sequence'},
overlay_status => $biblio->{'overlay_status'},
match_biblionumber => $#$match > -1 ? $match->[0]->{'biblionumber'} : 0,
match_citation => $#$match > -1 ? $match->[0]->{'title'} . ' ' . $match->[0]->{'author'} : '',
match_score => $#$match > -1 ? $match->[0]->{'score'} : 0,
};
}
my $num_biblios = $batch->{'num_biblios'};
$template->param(biblio_list => \@list);
add_page_numbers($template, $offset, $results_per_page, $num_biblios);
$template->param(offset => $offset);
$template->param(range_top => $offset + $results_per_page - 1);
$template->param(num_results => $num_biblios);
$template->param(results_per_page => $results_per_page);
$template->param(import_batch_id => $import_batch_id);
batch_info($template, $batch);
}
sub batch_info {
my ($template, $batch) = @_;
$template->param(batch_info => 1);
$template->param(file_name => $batch->{'file_name'});
$template->param(comments => $batch->{'comments'});
$template->param(import_status => $batch->{'import_status'});
$template->param(upload_timestamp => $batch->{'upload_timestamp'});
$template->param(num_biblios => $batch->{'num_biblios'});
$template->param(num_items => $batch->{'num_biblios'});
if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') {
$template->param(can_commit => 1);
}
if ($batch->{'import_status'} eq 'imported') {
$template->param(can_revert => 1);
}
}
sub add_page_numbers {
my ($template, $offset, $results_per_page, $total_results) = @_;
my $max_pages = POSIX::ceil($total_results / $results_per_page);
return if $max_pages < 2;
my $current_page = int($offset / $results_per_page) + 1;
my @pages = ();
for (my $i = 1; $i <= $max_pages; $i++) {
push @pages, {
page_number => $i,
current_page => ($current_page == $i) ? 1 : 0,
offset => ($i - 1) * $results_per_page
}
}
$template->param(pages => \@pages);
}

70
tools/import.pl → tools/stage-marc-import.pl

@ -36,7 +36,6 @@ use C4::Auth;
use C4::Input;
use C4::Output;
use C4::Biblio;
use C4::Breeding;
use C4::ImportBatch;
use C4::Matcher;
@ -60,11 +59,11 @@ my $input = new CGI;
my $dbh = C4::Context->dbh;
my $uploadmarc=$input->param('uploadmarc');
my $overwrite_biblio = $input->param('overwrite_biblio');
my $check_for_matches = $input->param('check_for_matches');
my $comments = $input->param('comments');
my $syntax = $input->param('syntax');
my ($template, $loggedinuser, $cookie)
= get_template_and_user({template_name => "tools/import.tmpl",
= get_template_and_user({template_name => "tools/stage-marc-import.tmpl",
query => $input,
type => "intranet",
authnotrequired => 0,
@ -80,60 +79,29 @@ if ($uploadmarc && length($uploadmarc)>0) {
while (<$uploadmarc>) {
$marcrecord.=$_;
}
#my ($notmarcrecord,$alreadyindb,$alreadyinfarm,$imported) = ImportBreeding($marcrecord,$overwrite_biblio,$filename,$syntax,int(rand(99999)), 'batch');
# FIXME branch code
my ($batch_id, $num_valid, @import_errors) = BatchStageMarcRecords($syntax, $marcrecord, $filename, $comments, '', 1);
my ($batch_id, $num_valid, @import_errors) = BatchStageMarcRecords($syntax, $marcrecord, $filename, $comments, '', 0);
my $matcher = C4::Matcher->new('biblio');
$matcher->add_matchpoint("020", "a", '', 'isbn', 1000);
my $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher);
my ($num_added, $num_updated, $num_ignored) = BatchCommitBibRecords($batch_id);
$template->param(imported => $num_valid,
alreadyindb => $num_with_matches,
alreadyinfarm => 0,
notmarcrecord => scalar(@import_errors),
total => $num_valid + scalar(@import_errors)
);
my $num_with_matches = 0;
my $checked_matches = 0;
if ($check_for_matches) {
$checked_matches = 1;
$num_with_matches = BatchFindBibDuplicates($batch_id, $matcher);
}
# FIXME we're not committing now
# my ($num_added, $num_updated, $num_ignored) = BatchCommitBibRecords($batch_id);
$template->param(staged => $num_valid,
matched => $num_with_matches,
import_errors => scalar(@import_errors),
total => $num_valid + scalar(@import_errors),
checked_matches => $checked_matches,
import_batch_id => $batch_id
);
}
output_html_with_http_headers $input, $cookie, $template->output;
#---------------
# log cleared, as marcimport is (almost) rewritten from scratch.
#
# Revision 1.5 2007/04/24 13:54:30 hdl
# functions that were in C4::Interface::CGI::Output are now in C4::Output.
# So this implies quite a change for files.
# Sorry about conflicts which will be caused.
# directory Interface::CGI should now be dropped.
# I noticed that many scripts (reports ones, but also some circ/stats.pl or opac-topissues) still use Date::Manip.
#
# Revision 1.4 2007/03/09 15:14:47 tipaul
# rel_3_0 moved to HEAD
#
# Revision 1.1.2.4 2006/12/22 17:13:49 tipaul
# removing "management" permission, that is useless (replaced by tools & admin)
#
# Revision 1.1.2.3 2006/12/18 16:35:20 toins
# removing use HTML::Template from *.pl.
#
# Revision 1.1.2.2 2006/10/03 12:27:32 toins
# the script was written twice into the file !
#
# Revision 1.1.2.1 2006/09/26 13:42:54 toins
# fix wrong link to breeding.tmpl
#
# Revision 1.1 2006/02/24 11:52:38 hdl
# Adding tools directory template and scripts
# Changing barcodes, export and import and letters directory.
# Changing export script name (marc.pl) to export.pl
# Changing import script name (breeding.pl) to import.pl
#
# Revision 1.4 2005/05/04 08:52:13 tipaul
# synch'ing 2.2 and head
#
# Revision 1.3 2005/03/23 09:57:47 doxulting
# Adding a parameter to allow acces to people with management/tools flags
Loading…
Cancel
Save