diff --git a/C4/ImportBatch.pm b/C4/ImportBatch.pm index 3ce5c67e59..52d4c05e89 100644 --- a/C4/ImportBatch.pm +++ b/C4/ImportBatch.pm @@ -514,7 +514,7 @@ sub BatchFindDuplicates { =head2 BatchCommitRecords - my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) = + my ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored) = BatchCommitRecords($batch_id, $framework, $progress_interval, $progress_callback); @@ -539,6 +539,7 @@ sub BatchCommitRecords { my $num_added = 0; my $num_updated = 0; my $num_items_added = 0; + my $num_items_replaced = 0; my $num_items_errored = 0; my $num_ignored = 0; # commit (i.e., save, all records in the batch) @@ -598,9 +599,10 @@ sub BatchCommitRecords { my $biblioitemnumber; ($recordid, $biblioitemnumber) = AddBiblio($marc_record, $framework); $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?"; - if ($item_result eq 'create_new') { - my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid); + if ($item_result eq 'create_new' || $item_result eq 'replace') { + my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result); $num_items_added += $bib_items_added; + $num_items_replaced += $bib_items_replaced; $num_items_errored += $bib_items_errored; } } else { @@ -631,9 +633,10 @@ sub BatchCommitRecords { ModBiblio($marc_record, $recordid, $oldbiblio->{'frameworkcode'}); $query = "UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?"; - if ($item_result eq 'create_new') { - my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid); + if ($item_result eq 'create_new' || $item_result eq 'replace') { + my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result); $num_items_added += $bib_items_added; + $num_items_replaced += $bib_items_replaced; $num_items_errored += $bib_items_errored; } } else { @@ -654,8 +657,9 @@ sub BatchCommitRecords { $num_ignored++; $recordid = $record_match; if ($record_type eq 'biblio' and defined $recordid and $item_result eq 'create_new') { - my ($bib_items_added, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid); + my ($bib_items_added, $bib_items_replaced, $bib_items_errored) = BatchCommitItems($rowref->{'import_record_id'}, $recordid, $item_result); $num_items_added += $bib_items_added; + $num_items_replaced += $bib_items_replaced; $num_items_errored += $bib_items_errored; # still need to record the matched biblionumber so that the # items can be reverted @@ -668,7 +672,7 @@ sub BatchCommitRecords { } $sth->finish(); SetImportBatchStatus($batch_id, 'imported'); - return ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored); + return ($num_added, $num_updated, $num_items_added, $num_items_replaced, $num_items_errored, $num_ignored); } =head2 BatchCommitItems @@ -679,12 +683,11 @@ sub BatchCommitRecords { =cut sub BatchCommitItems { - my ($import_record_id, $biblionumber) = @_; + my ($import_record_id, $biblionumber, $action) = @_; my $dbh = C4::Context->dbh; - my $num_items_added = 0; - my $num_items_errored = 0; + my ($num_items_added, $num_items_errored, $num_items_replaced) = 0; my $sth = $dbh->prepare("SELECT import_items_id, import_items.marcxml, encoding FROM import_items JOIN import_records USING (import_record_id) @@ -694,11 +697,24 @@ sub BatchCommitItems { $sth->execute(); while (my $row = $sth->fetchrow_hashref()) { my $item_marc = MARC::Record->new_from_xml(StripNonXmlChars($row->{'marcxml'}), 'UTF-8', $row->{'encoding'}); + #delete date_due subfield as to not accidentally delete item checkout due dates + my ($MARCfield,$MARCsubfield) = GetMarcFromKohaField('items.onloan', GetFrameworkCode($biblionumber)); + $item_marc->field($MARCfield)->delete_subfield(code => $MARCsubfield); # FIXME - duplicate barcode check needs to become part of AddItemFromMarc() my $item = TransformMarcToKoha($dbh, $item_marc); my $duplicate_barcode = exists($item->{'barcode'}) && GetItemnumberFromBarcode($item->{'barcode'}); - if ($duplicate_barcode) { - my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, import_error = ? WHERE import_items_id = ?"); + my $duplicate_itemnumber = exists($item->{'itemnumber'}); + my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?"); + if($action eq "replace" && $duplicate_itemnumber){ + ModItemFromMarc($item_marc, $biblionumber, $item->{itemnumber}); + $updsth->bind_param(1, 'imported'); + $updsth->bind_param(2, $item->{itemnumber}); + $updsth->bind_param(3, $row->{'import_items_id'}); + $updsth->execute(); + $updsth->finish(); + $num_items_replaced++; + } + elsif ($duplicate_barcode) { $updsth->bind_param(1, 'error'); $updsth->bind_param(2, 'duplicate item barcode'); $updsth->bind_param(3, $row->{'import_items_id'}); @@ -706,7 +722,6 @@ sub BatchCommitItems { $num_items_errored++; } else { my ($item_biblionumber, $biblioitemnumber, $itemnumber) = AddItemFromMarc($item_marc, $biblionumber); - my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?"); $updsth->bind_param(1, 'imported'); $updsth->bind_param(2, $itemnumber); $updsth->bind_param(3, $row->{'import_items_id'}); @@ -716,7 +731,7 @@ sub BatchCommitItems { } } $sth->finish(); - return ($num_items_added, $num_items_errored); + return ($num_items_added, $num_items_replaced, $num_items_errored); } =head2 BatchRevertRecords @@ -1467,7 +1482,15 @@ sub _get_commit_action { } elsif ($overlay_action eq 'ignore') { $bib_result = 'ignore'; } - $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_matches') ? 'create_new' : 'ignore'; + if($item_action eq 'always_add' or $item_action eq 'add_only_for_matches'){ + $item_result = 'create_new'; + } + elsif($item_action eq 'replace'){ + $item_result = 'replace'; + } + else { + $item_result = 'ignore'; + } } else { $bib_result = $nomatch_action; $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ? 'create_new' : 'ignore'; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 17615c5788..a6a779e97d 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -970,7 +970,7 @@ CREATE TABLE `import_batches` ( -- information about batches of marc records tha `upload_timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP, -- date and time the file was uploaded `overlay_action` enum('replace', 'create_new', 'use_template', 'ignore') NOT NULL default 'create_new', -- how to handle duplicate records `nomatch_action` enum('create_new', 'ignore') NOT NULL default 'create_new', -- how to handle records where no match is found - `item_action` enum('always_add', 'add_only_for_matches', 'add_only_for_new', 'ignore') NOT NULL default 'always_add', -- what to do with item records + `item_action` enum('always_add', 'add_only_for_matches', 'add_only_for_new', 'ignore', 'replace') NOT NULL default 'always_add', -- what to do with item records `import_status` enum('staging', 'staged', 'importing', 'imported', 'reverting', 'reverted', 'cleaned') NOT NULL default 'staging', -- the status of the imported file `batch_type` enum('batch', 'z3950', 'webservice') NOT NULL default 'batch', -- where this batch has come from `record_type` enum('biblio', 'auth', 'holdings') NOT NULL default 'biblio', -- type of record in the batch diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-item-action.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-item-action.inc index 0c8d37b003..9b5486980d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-item-action.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-item-action.inc @@ -17,6 +17,12 @@ + [% IF ( item_action_replace ) %] + [% IF ( item_action_ignore ) %]