Best Match w/ quality ratio merging
authorberick <berick@esilibrary.com>
Wed, 4 May 2011 21:15:03 +0000 (17:15 -0400)
committerBill Erickson <berick@esilibrary.com>
Wed, 6 Jul 2011 18:50:51 +0000 (14:50 -0400)
 * Mew Best Match option in merge/overlay
 * support for upload time minimum record quality ratio
 * We now /only/ create new records if no matches exist and the user
   selected a match-free import
 * Selecting a match-free import no longer trumps other merge imports.
   They both work together now.

TODO: find out why queued record quality is not getting set at queued
rec creation time.

Open-ILS/src/perlmods/lib/OpenILS/Application/Vandelay.pm
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/web/js/ui/default/vandelay/vandelay.js
Open-ILS/web/opac/locale/en-US/vandelay.dtd
Open-ILS/web/templates/default/vandelay/inc/matches.tt2
Open-ILS/web/templates/default/vandelay/inc/upload.tt2

index 510d6bf..759a624 100644 (file)
@@ -708,11 +708,15 @@ sub import_record_list_impl {
 
     my $auto_overlay_exact = $$args{auto_overlay_exact};
     my $auto_overlay_1match = $$args{auto_overlay_1match};
+    my $auto_overlay_best = $$args{auto_overlay_best_match};
+    my $match_quality_ratio = $$args{match_quality_ratio};
     my $merge_profile = $$args{merge_profile};
     my $bib_source = $$args{bib_source};
+    my $import_no_match = $$args{import_no_match};
 
     my $overlay_func = 'vandelay.overlay_bib_record';
     my $auto_overlay_func = 'vandelay.auto_overlay_bib_record';
+    my $auto_overlay_best_func = 'vandelay.auto_overlay_bib_record_with_best'; # XXX bib-only
     my $retrieve_func = 'retrieve_vandelay_queued_bib_record';
     my $update_func = 'update_vandelay_queued_bib_record';
     my $search_func = 'search_vandelay_queued_bib_record';
@@ -863,7 +867,39 @@ sub import_record_list_impl {
                 }
             }
 
-            if(!$imported and !$error) {
+            if(!$imported and !$error and $auto_overlay_best and scalar(@{$rec->matches}) > 0 ) {
+
+                # caller says to overlay the best match
+
+                my $res = $e->json_query(
+                    {
+                        from => [
+                            $auto_overlay_best_func,
+                            $rec->id, 
+                            $merge_profile,
+                            $match_quality_ratio
+                        ]
+                    }
+                );
+
+                if($res and ($res = $res->[0])) {
+
+                    if($res->{$auto_overlay_best_func} eq 't') {
+                        $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;
+                        $logger->info("vl: $type auto-overlay-best failed for queued rec " . $rec->id);
+                    }
+
+                } else {
+                    $error = 1;
+                    $logger->error("vl: Error attempting overlay with func=$auto_overlay_best_func, ".
+                        "quality_ratio=$match_quality_ratio, profile=$merge_profile, record=$rec_id");
+                }
+            }
+
+            if(!$imported and !$error and $import_no_match and scalar(@{$rec->matches}) == 0) {
             
                 # No overlay / merge occurred.  Do a traditional record import by creating a new record
             
index e45999d..0ad9ad0 100644 (file)
@@ -8667,6 +8667,7 @@ INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.missin
 INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.auth.duplicate.acn', oils_i18n_gettext('import.auth.duplicate.acn', 'Import failed due to Accession Number collision', 'vie', 'description') );
 INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'import.xml.malformed', oils_i18n_gettext('import.xml.malformed', 'Malformed record cause Import failure', 'vie', 'description') );
 INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.xml.malformed', oils_i18n_gettext('overlay.xml.malformed', 'Malformed record cause Overlay failure', 'vie', 'description') );
+INSERT INTO vandelay.import_error ( code, description ) VALUES ( 'overlay.record.quality', oils_i18n_gettext('overlay.record.quality', 'New record had insufficient quality', 'vie', 'description') );
 
 INSERT INTO config.org_unit_setting_type ( name, label, description, datatype ) VALUES (
     'ui.cat.volume_copy_editor.horizontal',
index 5b000b7..4aeef8f 100644 (file)
@@ -974,7 +974,7 @@ function vlHandleQueueItemsAction(action) {
             queueItemsImportDialog.hide();
 
             // hack to set the widgets the import funcs will be looking at.  Reset them below.
-            vlUploadQueueAutoImport.attr('value',  vlUploadQueueAutoImport2.attr('value'));
+            vlUploadQueueImportNoMatch.attr('value',  vlUploadQueueImportNoMatch2.attr('value'));
             vlUploadQueueAutoOverlayExact.attr('value',  vlUploadQueueAutoOverlayExact2.attr('value'));
             vlUploadQueueAutoOverlay1Match.attr('value',  vlUploadQueueAutoOverlay1Match2.attr('value'));
             vlUploadMergeProfile.attr('value',  vlUploadMergeProfile2.attr('value'));
@@ -986,8 +986,8 @@ function vlHandleQueueItemsAction(action) {
             }
             
             // reset the widgets to prevent accidental future actions
-            vlUploadQueueAutoImport.attr('value',  false);
-            vlUploadQueueAutoImport2.attr('value', false);
+            vlUploadQueueImportNoMatch.attr('value',  false);
+            vlUploadQueueImportNoMatch2.attr('value', false);
             vlUploadQueueAutoOverlayExact.attr('value', false);
             vlUploadQueueAutoOverlayExact2.attr('value', false);
             vlUploadQueueAutoOverlay1Match.attr('value', false);
@@ -1054,23 +1054,45 @@ function vlImportAllRecords() {
         function(){displayGlobalDiv('vl-queue-div');});
 }
 
-function vlImportRecordQueue(type, queueId, noMatchOnly, onload) {
+function vlImportRecordQueue(type, queueId, onload) {
     displayGlobalDiv('vl-generic-progress-with-total');
     var method = 'open-ils.vandelay.bib_queue.import';
-    if(noMatchOnly)
-        method = method.replace('import', 'nomatch.import');
     if(type == 'auth')
         method = method.replace('bib', 'auth');
 
+
+    var mergeOpt = false;
     var options = {};
+
+    if(vlUploadQueueImportNoMatch.checked) {
+        options.import_no_match = true;
+        vlUploadQueueImportNoMatch.checked = false;
+    }
+
     if(vlUploadQueueAutoOverlayExact.checked) {
         options.auto_overlay_exact = true;
         vlUploadQueueAutoOverlayExact.checked = false;
+        mergeOpt = true;
+    }
+
+    if(vlUploadQueueAutoOverlayBestMatch.checked) {
+        options.auto_overlay_best_match = true;
+        vlUploadQueueAutoOverlayBestMatch.checked = false;
+        options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
+        mergeOpt = true;
     }
 
     if(vlUploadQueueAutoOverlay1Match.checked) {
         options.auto_overlay_1match = true;
         vlUploadQueueAutoOverlay1Match.checked = false;
+        mergeOpt = true;
+    }
+
+    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');
     }
     
     var profile = vlUploadMergeProfile.attr('value');
@@ -1102,16 +1124,19 @@ function batchUpload() {
     currentType = dijit.byId('vl-record-type').getValue();
 
     var handleProcessSpool = function() {
-        if(vlUploadQueueAutoImport.checked || vlUploadQueueAutoOverlayExact.checked || vlUploadQueueAutoOverlay1Match.checked) {
-            var noMatchOnly = !vlUploadQueueAutoOverlayExact.checked && !vlUploadQueueAutoOverlay1Match.checked;
-            vlImportRecordQueue(
-                currentType, 
-                currentQueueId, 
-                noMatchOnly,
-                function() {
-                    retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
-                }
-            );
+        if( 
+            vlUploadQueueImportNoMatch.checked || 
+            vlUploadQueueAutoOverlayExact.checked || 
+            vlUploadQueueAutoOverlay1Match.checked ||
+            vlUploadQueueAutoOverlayBestMatch.checked ) {
+
+                vlImportRecordQueue(
+                    currentType, 
+                    currentQueueId, 
+                    function() {
+                        retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+                    }
+                );
         } else {
             retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
         }
index 48db0a6..d2d1789 100644 (file)
@@ -6,6 +6,7 @@
 <!ENTITY vandelay.auto.import.auto_overlay_1match "Merge/Overlay Single Matches">
 <!ENTITY vandelay.auto.import.auto_overlay_best "Merge/Overlay Best Match">
 <!ENTITY vandelay.auto.import.auto_overlay_best_ratio "Best Match Minimum Quality Ratio">
+<!ENTITY vandelay.auto.import.auto_overlay_best_ratio.desc "New Record Quaility / Quality of Best Match">
 <!ENTITY vandelay.auto.import.merge_profile "Merge/Overlay Profile">
 <!ENTITY vandelay.auto.width "Auto Width">
 <!ENTITY vandelay.back.to.import.queue "Back To Import Queue">
index 9cccbdb..40d6a80 100644 (file)
@@ -15,7 +15,7 @@
                     formatter : vlFormatViewMatchMARC
                 },
                 {name: 'Match Score', field:'match_score'},
-                {name: 'Match Quality', field:'match_quality'},
+                {name: 'Matched Record Quality', field:'match_quality'},
                 {name: '&vandelay.creator;', get: vlGetCreator},
                 {name: '&vandelay.create.date;', field:'create_date', get: vlGetDateTimeField},
                 {name: '&vandelay.last.edit.date;', field:'edit_date', get: vlGetDateTimeField},
index 8462ebc..f742104 100644 (file)
@@ -54,7 +54,7 @@
         <tr>
             <td>&vandelay.auto.import.noncolliding;</td>
             <td colspan='4'>
-                <input jsId='vlUploadQueueAutoImport' dojoType='dijit.form.CheckBox'/>
+                <input jsId='vlUploadQueueImportNoMatch' dojoType='dijit.form.CheckBox'/>
             </td>
         </tr>
         <tr>
         </tr>
         <tr>
             <td>&vandelay.auto.import.auto_overlay_best_ratio;</td>
-            <td colspan='4'><input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio' dojoType='dijit.form.TextBox'/></td>
+            <td colspan='4'>
+                <input style='width:3em' value='0.0' jsId='vlUploadQueueAutoOverlayBestMatchRatio' dojoType='dijit.form.TextBox'/>
+                <span style='padding-left: 10px; font-size:90%'>(&vandelay.auto.import.auto_overlay_best_ratio.desc;)</span>
+            </td>
         </tr>
 
         <tr><td colspan='2' style='border-bottom:1px solid #888'></td></tr>