From 25ee42bb2453c1d540b93bae206b28b1a53feb4b Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Fri, 29 Jun 2018 14:45:27 -0400 Subject: [PATCH] LP#1642344: XUL report cloning This patch allows report templates of version 4 and earlier (which would have been created by the XUL staff client) to be upgraded to template version 5 (used by the web staff client) when the user clones a report. This closes a limitation introduced in the reporter module for the web staff client. Note that during the conversion, inner joins are used by default when IDL classes have a 'has_a' relation rather than defaulting to left outer joins, improving correctness of the generated SQL query. To test ------- [0] Apply the patch. [1] In a test database that has reporter templates created by (or for) the XUL staff client, create clones of those templates. [2] Verify that the output of reports created using the new templates matches output of reports from the original templates. Signed-off-by: Galen Charlton Signed-off-by: Terran McCanna Signed-off-by: Mike Rylander --- .../js/ui/default/staff/reporter/template/app.js | 129 ++++++++++++++++++--- .../js/ui/default/staff/test/unit/egReporter.js | 24 ++++ Open-ILS/web/reports/oils_rpt_folder_window.js | 5 +- 3 files changed, 140 insertions(+), 18 deletions(-) diff --git a/Open-ILS/web/js/ui/default/staff/reporter/template/app.js b/Open-ILS/web/js/ui/default/staff/reporter/template/app.js index b50dabc021..c79a54bf37 100644 --- a/Open-ILS/web/js/ui/default/staff/reporter/template/app.js +++ b/Open-ILS/web/js/ui/default/staff/reporter/template/app.js @@ -257,29 +257,128 @@ function($scope , $q , $routeParams , $location , $timeout , $window, egCore , } + $scope.upgradeTemplate = function(template) { + template.name(template.name() + ' (converted from XUL)'); + template.data.version = 5; + + var order_by; + var rels = []; + for (var key in template.data.rel_cache) { + if (key == 'order_by') { + order_by = template.data.rel_cache[key]; + } else { + rels.push(template.data.rel_cache[key]); + } + } + + template.data['display_cols'] = []; + template.data['filter_cols'] = []; + + var dispcol_index = 0; + + function _convertPath(orig, rel) { + var newPath = []; + + var table_path = rel.path.split(/\./); + if (table_path.length > 1 || rel.path.indexOf('-') > -1) table_path.push( rel.idlclass ); + + var prev_type = ''; + var prev_link = ''; + table_path.forEach(function(link) { + var cls = link.split(/-/)[0]; + var fld = link.split(/-/)[1]; + var args = { + label : egCore.idl.classes[cls].label + } + if (prev_link != '') { + args['from'] = prev_link.split(/-/)[0]; + var prev_col = prev_link.split(/-/)[1].split(/>/)[0]; + egCore.idl.classes[prev_link.split(/-/)[0]].fields.forEach(function(f) { + if (prev_col == f.name) { + args['link'] = f; + } + }); + } + newPath.push(egCore.idl.classTree.buildNode(cls, args)); + prev_link = link; + }); + return newPath; + + } + + rels.map(function(rel) { + for (var col in rel.fields.dis_tab) { + var orig = rel.fields.dis_tab[col]; + var display_col = { + name : orig.colname, + path : _convertPath(orig, rel), + index : dispcol_index++, + label : orig.alias, + datatype : orig.datatype, + doc_text : orig.field_doc, + transform : { + label : orig.transform_label, + transform : orig.transform, + aggregate : orig.aggregate + }, + path_label : rel.label + }; + template.data.display_cols.push(display_col); + } + }); + + rels.map(function(rel) { + for (var col in rel.fields.filter_tab) { + var orig = rel.fields.filter_tab[col]; + var filter_col = { + name : orig.colname, + path : _convertPath(orig, rel), + index : dispcol_index++, + label : orig.alias, + datatype : orig.datatype, + doc_text : orig.field_doc, + operator : { + op : orig.op, + label : orig.op_label + }, + transform : { + label : orig.transform_label, + transform : orig.transform, + aggregate : orig.aggregate + }, + path_label : rel.label + }; + if ('value' in orig.op_value) { + filter_col['value'] = orig.op_value.value; + } + template.data.filter_cols.push(filter_col); + } + }); + + } + function loadTemplate () { if (!template_id) return; egCore.pcrud.retrieve( 'rt', template_id) .then( function(template) { template.data = angular.fromJson(template.data()); - if (template.data.version < 5) { // redirect to old editor... - $window.location.href = egCore.env.basePath + 'reporter/legacy/template/clone/'+folder_id + '/' + template_id; - // } else if (template.data.version < 5) { // redirect to old editor... - } else { - $scope.templateName = template.name() + ' (clone)'; - $scope.templateDescription = template.description(); - $scope.templateDocURL = template.data.doc_url; + if (template.data.version < 5) { + $scope.upgradeTemplate(template); + } - $scope.changeCoreSource( template.data.core_class ); + $scope.templateName = template.name() + ' (clone)'; + $scope.templateDescription = template.description(); + $scope.templateDocURL = template.data.doc_url; - egReportTemplateSvc.display_fields = template.data.display_cols; - egReportTemplateSvc.filter_fields = template.data.filter_cols; + $scope.changeCoreSource( template.data.core_class ); - $timeout(function(){ - dgrid.refresh(); - fgrid.refresh(); - }); - } + egReportTemplateSvc.display_fields = template.data.display_cols; + egReportTemplateSvc.filter_fields = template.data.filter_cols; + + $timeout(function(){ + dgrid.refresh(); + fgrid.refresh(); + }); }); } diff --git a/Open-ILS/web/js/ui/default/staff/test/unit/egReporter.js b/Open-ILS/web/js/ui/default/staff/test/unit/egReporter.js index 743483e0e9..1f51d403bf 100644 --- a/Open-ILS/web/js/ui/default/staff/test/unit/egReporter.js +++ b/Open-ILS/web/js/ui/default/staff/test/unit/egReporter.js @@ -182,4 +182,28 @@ describe('egReporterTest', function() { }); + /** template conversion tests **/ + var v4Templates = [ + '{"version":4,"doc_url":"","core_class":"bre","select":[{"alias":"Title Proper (normalized)","field_doc":"","column":{"colname":"title","transform":"Bare","transform_label":"Raw Data"},"path":"bre-simple_record-rmsr-title","relation":"938089c53626281c03f9f40622093fcc"}],"from":{"path":"bre-simple_record","table":"biblio.record_entry","alias":"a0a5898f5f47b01a3943462dbf1c45ad","join":{"id-mfr-record-a0a5898f5f47b01a3943462dbf1c45ad":{"key":"record","type":"left","path":"bre-full_record_entries-mfr","table":"metabib.full_rec","label":"Bibliographic Record :: Flattened MARC Fields ","alias":"6da08cb48d3b764920485d2d40a4145c","idlclass":"mfr","template_path":"bre-full_record_entries"},"id-rmsr-id-a0a5898f5f47b01a3943462dbf1c45ad":{"key":"id","type":"left","path":"bre-simple_record-rmsr","table":"reporter.materialized_simple_record","label":"Bibliographic Record :: Simple Record Extracts ","alias":"938089c53626281c03f9f40622093fcc","idlclass":"rmsr","template_path":"bre-simple_record"}}},"where":[{"alias":"Tag","field_doc":"","column":{"colname":"tag","transform":"Bare","transform_label":"Raw Data"},"path":"bre-full_record_entries-mfr-tag","relation":"6da08cb48d3b764920485d2d40a4145c","condition":{"ilike":"::P0"}},{"alias":"Subfield","field_doc":"","column":{"colname":"subfield","transform":"Bare","transform_label":"Raw Data"},"path":"bre-full_record_entries-mfr-subfield","relation":"6da08cb48d3b764920485d2d40a4145c","condition":{"ilike":"::P1"}},{"alias":"Normalized Value","field_doc":"","column":{"colname":"value","transform":"Bare","transform_label":"Raw Data"},"path":"bre-full_record_entries-mfr-value","relation":"6da08cb48d3b764920485d2d40a4145c","condition":{"ilike":"::P2"}}],"having":[],"order_by":[],"rel_cache":{"order_by":[{"relation":"938089c53626281c03f9f40622093fcc","field":"title"}],"6da08cb48d3b764920485d2d40a4145c":{"label":"Bibliographic Record :: Flattened MARC Fields ","alias":"6da08cb48d3b764920485d2d40a4145c","path":"bre-full_record_entries","join":"","reltype":"has_many","idlclass":"mfr","table":"metabib.full_rec","fields":{"dis_tab":{},"filter_tab":{"tag":{"colname":"tag","transform":"Bare","aggregate":null,"params":null,"transform_label":"Raw Data","alias":"Tag","field_doc":"","join":"","datatype":"text","op":"ilike","op_label":"Contains Matching substring (ignore case)","op_value":{}},"subfield":{"colname":"subfield","transform":"Bare","aggregate":null,"params":null,"transform_label":"Raw Data","alias":"Subfield","field_doc":"","join":"","datatype":"text","op":"ilike","op_label":"Contains Matching substring (ignore case)","op_value":{}},"value":{"colname":"value","transform":"Bare","aggregate":null,"params":null,"transform_label":"Raw Data","alias":"Normalized Value","field_doc":"","join":"","datatype":"text","op":"ilike","op_label":"Contains Matching substring (ignore case)","op_value":{}}},"aggfilter_tab":{}}},"938089c53626281c03f9f40622093fcc":{"label":"Bibliographic Record :: Simple Record Extracts ","alias":"938089c53626281c03f9f40622093fcc","path":"bre-simple_record","join":"","reltype":"might_have","idlclass":"rmsr","table":"reporter.materialized_simple_record","fields":{"dis_tab":{"title":{"colname":"title","transform":"Bare","aggregate":null,"params":null,"transform_label":"Raw Data","alias":"Title Proper (normalized)","field_doc":"","join":"","datatype":"text","op":"=","op_label":"Equals","op_value":{}}},"filter_tab":{},"aggfilter_tab":{}}}}}' + ]; + + describe('egReporterTemplateConversionTests', function() { + it('initialize for template conversion tests', inject(function(egIDL, egCore) { + egIDL.parseIDL(); + })); + it('test template conversion does not crash', inject(function(egIDL) { + angular.forEach(v4Templates, function(tmpl, i) { + var rt = new egIDL.rt(); + rt.data(tmpl); + rt.name('Test template #' + i); + rt.data = angular.fromJson(rt.data()); + expect(rt.data.version).toBeLessThan(5); + reportEditScope.changeCoreSource(rt.data.core_class); + reportEditScope.upgradeTemplate(rt); + expect(rt.data.version).toEqual(5); + }); + })); + }); + + }); diff --git a/Open-ILS/web/reports/oils_rpt_folder_window.js b/Open-ILS/web/reports/oils_rpt_folder_window.js index d1ba641179..488cba6222 100644 --- a/Open-ILS/web/reports/oils_rpt_folder_window.js +++ b/Open-ILS/web/reports/oils_rpt_folder_window.js @@ -3,7 +3,6 @@ dojo.requireLocalization("openils.reports", "reports"); var rpt_strings = dojo.i18n.getLocalization("openils.reports", "reports"); var NG_NEW_TEMPLATE_INTERFACE = '/eg/staff/reporter/template/new'; var NG_CLONE_TEMPLATE_INTERFACE = '/eg/staff/reporter/template/clone'; -var NG_CLONE_LEGACY_TEMPLATE_INTERFACE = '/eg/staff/reporter/legacy/template/clone'; var OILS_TEMPLATE_INTERFACE = 'xul/template_builder.xul'; var OILS_LEGACY_TEMPLATE_INTERFACE = 'oils_rpt_builder.xhtml'; @@ -338,14 +337,14 @@ oilsRptFolderWindow.prototype.cloneTemplate = function(template) { window.top.location.href = NG_CLONE_TEMPLATE_INTERFACE+'/'+folderid+'/'+template.id(); } else if(version && version >= 2) { if (window.IAMBROWSER) { - window.top.location.href = NG_CLONE_LEGACY_TEMPLATE_INTERFACE+'/'+folderid+'/'+template.id(); + window.top.location.href = NG_CLONE_TEMPLATE_INTERFACE+'/'+folderid+'/'+template.id(); } else { _debug('entering new template building interface with template version ' + version); goTo(OILS_TEMPLATE_INTERFACE+s+'&folder='+folderid+'&ct='+template.id()); } } else { if (window.IAMBROWSER) { - window.top.location.href = NG_CLONE_LEGACY_TEMPLATE_INTERFACE+'/'+folderid+'/'+template.id(); + window.top.location.href = NG_CLONE_TEMPLATE_INTERFACE+'/'+folderid+'/'+template.id(); } else { goTo(OILS_LEGACY_TEMPLATE_INTERFACE+s+'&folder='+folderid+'&ct='+template.id()); } -- 2.11.0