<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Import Items" name="import_items" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
<field reporter:label="Purpose" name="purpose" reporter:datatype="text"/>
<field reporter:label="Attributes" name="attributes" oils_persist:virtual="true" reporter:datatype="link"/>
<field reporter:label="Matches" name="matches" oils_persist:virtual="true" reporter:datatype="link"/>
+ <field reporter:label="Quality" name="quality" reporter:datatype="int"/>
</fields>
<links>
<link field="import_error" reltype="has_a" key="code" map="" class="vie"/>
return $e->die_event unless $e->checkauth;
$args ||= {};
my $err = import_record_list_impl($self, $conn, $rec_ids, $e->requestor, $args);
- $e->rollback;
+ try {$e->rollback} otherwise {};
return $err if $err;
return {complete => 1};
}
my $type = $self->{record_type};
my %queues;
- my %report_args = (
- progress => 0,
+ my $report_args = {
+ progress => 1,
step => 1,
conn => $conn,
total => scalar(@$rec_ids),
report_all => $$args{report_all}
- );
+ };
my $auto_overlay_exact = $$args{auto_overlay_exact};
my $auto_overlay_1match = $$args{auto_overlay_1match};
my $e = new_editor(xact => 1);
$e->requestor($requestor);
- $report_args{progress}++;
- $report_args{e} = $e;
- $report_args{import_error} = undef;
- $report_args{evt} = undef;
+ $$report_args{e} = $e;
+ $$report_args{import_error} = undef;
+ $$report_args{evt} = undef;
my $rec = $e->$retrieve_func([
$rec_id,
]);
unless($rec) {
- finish_rec_import_attempt(%report_args, evt => $e->event);
+ $$report_args{evt} = $e->event;
+ finish_rec_import_attempt($report_args);
next;
}
- $report_args{rec} = $rec;
+ $$report_args{rec} = $rec;
if($rec->import_time) {
$e->rollback;
$logger->info("vl: $type auto-overlay-best succeeded for queued rec " . $rec->id);
$imported = 1;
} else {
- $report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
+ $$report_args{import_error} = 'overlay.record.quality' if $match_quality_ratio > 0;
$logger->info("vl: $type auto-overlay-best failed for queued rec " . $rec->id);
}
}
if($U->event_code($record)) {
- $report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
- $report_args{evt} = $record;
+ $$report_args{import_error} = 'import.duplicate.tcn' if $record->{textcode} eq 'TCN_EXISTS';
+ $$report_args{evt} = $record;
} else {
if($imported) {
push @success_rec_ids, $rec_id;
- finish_rec_import_attempt(%report_args);
+ finish_rec_import_attempt($report_args);
} else {
# Send an update whenever there's an error
- finish_rec_import_attempt(%report_args, evt => $e->event);
+ $$report_args{evt} = $e->event unless $$report_args{evt};
+ finish_rec_import_attempt($report_args);
}
}
# import the copies
import_record_asset_list_impl($conn, \@success_rec_ids, $requestor);
- $conn->respond({total => $report_args{total}, progress => $report_args{progress}});
+ $conn->respond({total => $$report_args{total}, progress => $$report_args{progress}});
return undef;
}
# tracks any import errors, commits the current xact, responds to the client
sub finish_rec_import_attempt {
- my %args = @_;
- my $evt = $args{evt};
- my $rec = $args{rec};
- my $e = $args{e};
+ my $args = shift;
+ my $evt = $$args{evt};
+ my $rec = $$args{rec};
+ my $e = $$args{e};
- my $error = $args{import_error};
+ my $error = $$args{import_error};
$error = 'general.unknown' if $evt and not $error;
# error tracking
}
my $method = 'update_vandelay_queued_bib_record';
- $method =~ s/bib/authority/ if $args{type} eq 'auth';
+ $method =~ s/bib/authority/ if $$args{type} eq 'auth';
$e->$method($rec) and $e->commit or $e->rollback;
} else {
}
# respond to client
- if($args{report_all} or ($args{progress} % $args{step}) == 0) {
-
- $args{conn}->respond({
- total => $args{total},
- progress => $args{progress},
+ if($$args{report_all} or ($$args{progress} % $$args{step}) == 0) {
+ $$args{conn}->respond({
+ total => $$args{total},
+ progress => $$args{progress},
imported => ($rec) ? $rec->id : undef,
err_event => $evt
});
-
- # report often at first, climb quickly, then hold steady
- $args{step} *= 2 unless $args{step} == 256;
+ $$args{step} *= 2 unless $$args{step} == 256;
}
+
+ $$args{progress}++;
}
my $roe = new_editor(xact=> 1, requestor => $requestor);
+ # for speed, filter out any records have not been
+ # imported or have no import items to load
+ $rec_ids = $roe->json_query({
+ select => {vqbr => ['id']},
+ from => {vqbr => 'vii'},
+ where => {'+vqbr' => {import_time => {'!=' => undef}}}
+ });
+ $rec_ids = [map {$_->{id}} @$rec_ids];
+
my %report_args = (
conn => $conn,
total => scalar(@$rec_ids),
step => 1, # how often to respond
- progress => 0,
+ progress => 1,
in_count => 0,
);
for my $rec_id (@$rec_ids) {
my $rec = $roe->retrieve_vandelay_queued_bib_record($rec_id);
- next unless $rec and $rec->import_time;
my $item_ids = $roe->search_vandelay_import_item({record => $rec->id}, {idlist=>1});
for my $item_id (@$item_ids) {
my $e = new_editor(requestor => $requestor, xact => 1);
my $item = $e->retrieve_vandelay_import_item($item_id);
- $report_args{progress}++;
$report_args{import_item} = $item;
$report_args{e} = $e;
+ $report_args{import_error} = undef;
+ $report_args{evt} = undef;
# --------------------------------------------------------------------------------
# Find or create the volume
respond_with_status(%report_args, imported_as => $copy->id);
$logger->info("vl: successfully imported item " . $item->barcode);
}
+
}
+
$roe->rollback;
return undef;
}
sub respond_with_status {
- my %args = @_;
- my $e = $args{e};
+ my $args = shift;
+ my $e = $$args{e};
# If the import failed, track the failure reason
- my $error = $args{import_error};
- my $evt = $args{evt};
+ my $error = $$args{import_error};
+ my $evt = $$args{evt};
if($error or $evt) {
- my $item = $args{import_item};
+ my $item = $$args{import_item};
$logger->info("vl: unable to import item " . $item->barcode);
$error ||= 'general.unknown';
$e->commit;
}
- return unless $args{report_all} or ($args{progress} % $args{step}) == 0;
- $args{step} *= 2 unless $args{step} == 256;
+ if($$args{report_all} or ($$args{progress} % $$args{step}) == 0) {
+ $$args{conn}->respond({
+ map { $_ => $args->{$_} } qw/total progress success_count/,
+ err_event => $evt
+ });
+ $$args{step} *= 2 unless $$args{step} == 256;
+ }
- $args{conn}->respond({
- map { $_ => $args{$_} } qw/total progress success_count/,
- err_event => $evt
- });
+ $$args{progress}++;
}
__PACKAGE__->register_method(
function vlLoadMatchUI(recId) {
displayGlobalDiv('vl-generic-progress');
- var matches = queuedRecordsMap[recId].matches();
+ var queuedRec = queuedRecordsMap[recId];
+ var matches = queuedRec.matches();
var records = [];
currentImportRecId = recId;
for(var i = 0; i < matches.length; i++)
// build the data store of records with match information
var dataStore = bre.toStoreData(recs, null,
- {virtualFields:['_id', 'match_score', 'match_quality']});
+ {virtualFields:['_id', 'match_score', 'match_quality', 'rec_quality']});
dataStore.identifier = '_id';
var matchSeenMap = {};
if(match.match_score)
item.match_score = match.match_score();
item.match_quality = match.quality();
+ item.rec_quality = queuedRec.quality();
matchSeenMap[match.id()] = 1;
break;
}
vlUploadQueueAutoOverlayExact.attr('value', vlUploadQueueAutoOverlayExact2.attr('value'));
vlUploadQueueAutoOverlay1Match.attr('value', vlUploadQueueAutoOverlay1Match2.attr('value'));
vlUploadMergeProfile.attr('value', vlUploadMergeProfile2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatch.attr('value', vlUploadQueueAutoOverlayBestMatch2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', vlUploadQueueAutoOverlayBestMatchRatio2.attr('value'));
if(action == 'import') {
vlImportSelectedRecords();
vlUploadQueueAutoOverlay1Match2.attr('value', false);
vlUploadMergeProfile.attr('value', '');
vlUploadMergeProfile2.attr('value', '');
+ vlUploadQueueAutoOverlayBestMatch.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatch2.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', '0.0');
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', '0.0');
}
);
}
+/* import user-selected records */
function vlImportSelectedRecords() {
- displayGlobalDiv('vl-generic-progress-with-total');
var records = [];
for(var id in selectableGridRecords) {
}
}
- var options = {overlay_map : currentOverlayRecordsMap};
-
- if(vlUploadQueueAutoOverlayExact.checked) {
- options.auto_overlay_exact = true;
- vlUploadQueueAutoOverlayExact.checked = false;
- }
-
- if(vlUploadQueueAutoOverlay1Match.checked) {
- options.auto_overlay_1match = true;
- vlUploadQueueAutoOverlay1Match.checked = false;
- }
-
- var profile = vlUploadMergeProfile.attr('value');
- if(profile != null && profile != '') {
- options.merge_profile = profile;
- }
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+currentType+'_record.list.import'],
- { async: true,
- params: [authtoken, records, options],
- onresponse: function(r) {
- var resp = r.recv().content();
- if(e = openils.Event.parse(resp))
- return alert(e);
- if(resp.complete) {
- return retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- } else {
- vlControlledProgressBar.update({maximum:resp.total, progress:resp.progress});
- }
- },
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ records,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
}
);
}
+/* import all (non-imported) queue records */
function vlImportAllRecords() {
- vlImportRecordQueue(currentType, currentQueueId, false,
- function(){displayGlobalDiv('vl-queue-div');});
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ null,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
}
-function vlImportRecordQueue(type, queueId, onload) {
+/* if recList has values, import only those records */
+function vlImportRecordQueue(type, queueId, recList, onload) {
displayGlobalDiv('vl-generic-progress-with-total');
- var method = 'open-ils.vandelay.bib_queue.import';
- if(type == 'auth')
- method = method.replace('bib', 'auth');
-
+ /* set up options */
var mergeOpt = false;
- var options = {};
+ var options = {overlay_map : currentOverlayRecordsMap};
if(vlUploadQueueImportNoMatch.checked) {
options.import_no_match = true;
mergeOpt = true;
}
+ var profile = vlUploadMergeProfile.attr('value');
+ if(profile != null && profile != '') {
+ options.merge_profile = profile;
+ }
+
+ /* determine which method we're calling */
+
+ var method = 'open-ils.vandelay.bib_queue.import';
+ if(type == 'auth')
+ method = method.replace('bib', 'auth');
+
if(!mergeOpt) {
// in the interest of speed, if no merge options are
// chosen, tell the back-end code to only process records
// that have no matches
- method = method.replace('.import', 'nomatch.import');
+ method = method.replace(/\.import/, '.nomatch.import');
}
-
- var profile = vlUploadMergeProfile.attr('value');
- if(profile != null && profile != '') {
- options.merge_profile = profile;
+
+ var params = [authtoken, queueId, options];
+ if(recList) {
+ method = 'open-ils.vandelay.'+currentType+'_record.list.import';
+ params[1] = recList;
}
fieldmapper.standardRequest(
['open-ils.vandelay', method],
{ async: true,
- params: [authtoken, queueId, options],
+ params: params,
onresponse: function(r) {
var resp = r.recv().content();
if(e = openils.Event.parse(resp))
vlImportRecordQueue(
currentType,
currentQueueId,
+ null,
function() {
retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
}
vlUploadQueueAutoOverlayBestMatchRatio.attr('value', profile.lwm_ratio()+'');
}
);
+ dojo.connect(
+ vlUploadMergeProfile2,
+ 'onChange',
+ function(val) {
+ if(!val) return;
+ var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
+ if(profile.lwm_ratio() != null)
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', profile.lwm_ratio()+'');
+ }
+ );
+
}
function vlShowQueueSelect() {
formatter : vlFormatViewMatchMARC
},
{name: 'Match Score', field:'match_score'},
+ {name: 'Queued Record Quality', field:'rec_quality'},
{name: 'Matched Record Quality', field:'match_quality'},
{name: '&vandelay.creator;', get: vlGetCreator},
{name: '&vandelay.create.date;', field:'create_date', get: vlGetDateTimeField},
<table class='queue-nav-table'>
<thead><tr><th colspan='2' class='queue-nav-table-label'>Queue Actions</th></tr></thead>
<tbody>
- <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
- <tr><td><a href='#' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
- <tr><td><a href='#' onclick='vlLoadErrorUIAll();'>View Import Items</a></td></tr>
- <tr><td><a href='#' onclick='
+ <tr><td><a href='javascript:;' onclick='vlHandleQueueItemsAction("import")'>&vandelay.import.selected;</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='vlHandleQueueItemsAction("import_all")'>&vandelay.import.all;</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='vlLoadErrorUIAll();'>View Import Items</a></td></tr>
+ <tr><td><a href='javascript:;' onclick='
if(confirm("&vandelay.sure.to.delete.queue;")) {
vlDeleteQueue(currentType, currentQueueId,
function() { displayGlobalDiv("vl-marc-upload-div"); });}'>&vandelay.delete.queue;</a></td></tr>
<table class='form_table'>
<tbody>
<tr>
+ <td>&vandelay.auto.import.merge_profile;</td>
+ <td colspan='4'>
+ <div jsId='vlUploadMergeProfile2'
+ dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ </td>
+ </tr>
+ <tr>
<td>&vandelay.auto.import.noncolliding;</td>
<td colspan='4'>
- <input jsId='vlUploadQueueAutoImport2' dojoType='dijit.form.CheckBox'/>
+ <input jsId='vlUploadQueueImportNoMatch2' dojoType='dijit.form.CheckBox'/>
</td>
</tr>
<tr>
</td>
</tr>
<tr>
- <td>&vandelay.auto.import.merge_profile;</td>
+ <td>&vandelay.auto.import.auto_overlay_best;</td>
+ <td colspan='4'><input jsId='vlUploadQueueAutoOverlayBestMatch2' dojoType='dijit.form.CheckBox'/></td>
+ </tr>
+ <tr>
+ <td>&vandelay.auto.import.auto_overlay_best_ratio;</td>
<td colspan='4'>
- <div jsId='vlUploadMergeProfile2'
- dojoType='dijit.form.FilteringSelect' required='false' labelAttr='name' searchAttr='name'/>
+ <input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio2' dojoType='dijit.form.TextBox'/>
+ <span style='padding-left: 10px; font-size:90%'>(&vandelay.auto.import.auto_overlay_best_ratio.desc;)</span>
</td>
</tr>
<tr>