From: Bill Erickson Date: Wed, 30 May 2018 15:46:16 +0000 (-0400) Subject: LP#1750894 support getKeys() / batch of print template settings X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=42bb265aba64508d175557271167d0d7c69f0067;p=working%2FEvergreen.git LP#1750894 support getKeys() / batch of print template settings Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm index 6ab6818ef6..601188c9e9 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor/Settings.pm @@ -15,11 +15,11 @@ my $name_regex = qr/[^a-zA-Z0-9_\.]/; __PACKAGE__->register_method ( method => 'retrieve_settings', - api_name => 'open-ils.actor.settings.retrieve', + api_name => 'open-ils.actor.settings.retrieve', stream => 1, signature => { desc => q/ - Returns org unit, user, and workstation setting values + Returns org unit, user, and workstation setting values for the requested setting types. The API makes a best effort to find the correct setting @@ -28,8 +28,8 @@ __PACKAGE__->register_method ( If no auth token is provided, only publicly visible org unit settings may be returned. - If no workstation is linked to the provided auth token, only - user settings and perm-visible org unit settings may be + If no workstation is linked to the provided auth token, only + user settings and perm-visible org unit settings may be returned. If no org unit is provided, but a workstation is linked to the @@ -43,8 +43,8 @@ __PACKAGE__->register_method ( ], return => { desc => q/ - Stream of setting name=>value pairs in the same order - as the provided list of setting names. No key-value + Stream of setting name=>value pairs in the same order + as the provided list of setting names. No key-value pair is returned for settings that have no value defined./, type => 'string' } @@ -57,7 +57,7 @@ sub retrieve_settings { my ($aou_id, $user_id, $ws_id, $evt) = get_context($auth, $org_id); return $evt if $evt; # bogus auth token - return OpenILS::Event->new('BAD_PARAMS', + return OpenILS::Event->new('BAD_PARAMS', desc => 'Cannot retrieve settings without a user or org unit') unless ($user_id || $aou_id); @@ -67,12 +67,12 @@ sub retrieve_settings { # Encode as a db-friendly array. my $settings_str = '{' . join(',', @$settings) . '}'; - # Some settings could be bulky, so fetch them as a stream from + # Some settings could be bulky, so fetch them as a stream from # cstore, relaying values back to the caller as they arrive. my $ses = OpenSRF::AppSession->create('open-ils.cstore'); my $req = $ses->request('open-ils.cstore.json_query', { from => [ - 'actor.get_cascade_setting_batch', + 'actor.get_cascade_setting_batch', $settings_str, $aou_id, $user_id, $ws_id ] }); @@ -93,7 +93,7 @@ sub get_context { my ($auth, $org_id) = @_; return ($org_id) unless $auth; - + my $e = new_editor(authtoken => $auth); return (undef, undef, undef, $e->event) unless $e->checkauth; @@ -108,7 +108,7 @@ sub get_context { __PACKAGE__->register_method ( method => 'apply_user_or_ws_setting', - api_name => 'open-ils.actor.settings.apply.user_or_ws', + api_name => 'open-ils.actor.settings.apply.user_or_ws', stream => 1, signature => { desc => q/ @@ -156,7 +156,7 @@ sub apply_user_or_ws_setting { # Confirm the caller has permission to apply workstation # settings at the logged-in workstation before applying. # Do the perm check here so it's only needed once per batch. - return $e->die_event unless + return $e->die_event unless $ws_allowed = $e->allowed('APPLY_WORKSTATION_SETTING'); } @@ -235,4 +235,80 @@ sub apply_workstation_setting { return undef; } +__PACKAGE__->register_method ( + method => 'applied_settings', + api_name => 'open-ils.actor.settings.staff.applied.names', + stream => 1, + authoritative => 1, + signature => { + desc => q/ + Returns a list of setting names where a value is applied to + the current user or workstation. + + This is a staff-only API created primarily to support the + getKeys() functionality used in the browser client for + server-managed settings. + /, + params => [ + {desc => 'authtoken', type => 'string'}, + {desc => + 'prefix. Limit keys to those starting with $prefix', + type => 'string' + }, + ], + return => { + desc => 'List of strings, Event on error', + type => 'array' + } + } +); + +sub applied_settings { + my ($self, $client, $auth, $prefix) = @_; + + my $e = new_editor(authtoken => $auth); + return $e->event unless $e->checkauth; + + return $e->event unless + $e->allowed('STAFF_LOGIN') && + $e->allowed('APPLY_WORKSTATION_SETTING'); + + + my $query = { + select => {awss => ['name']}, + from => 'awss', + where => { + workstation => $e->requestor->wsid + } + }; + + $query->{where}->{name} = {like => "$prefix%"} if $prefix; + + for my $key (@{$e->json_query($query)}) { + $client->respond($key->{name}); + } + + $query = { + select => {aus => ['name']}, + from => 'aus', + where => { + usr => $e->requestor->id + } + }; + + $query->{where}->{name} = {like => "$prefix%"} if $prefix; + + for my $key (@{$e->json_query($query)}) { + $client->respond($key->{name}); + } + + return undef; +} + + + + + + + 1; diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql index a9f82fecdb..f43aef6e6d 100644 --- a/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql +++ b/Open-ILS/src/sql/Pg/upgrade/YYYY.data.workstation-settings.sql @@ -1,5 +1,8 @@ BEGIN; +INSERT INTO permission.perm_list (id, code, description) VALUES + (607, 'APPLY_WORKSTATION_SETTING', + oils_i18n_gettext(607, 'APPLY_WORKSTATION_SETTING', 'ppl', 'description')); INSERT INTO config.workstation_setting_type (name, grp, datatype, label) VALUES ( @@ -471,9 +474,380 @@ VALUES ( 'MARC Editor Stack Subfields', 'cwst', 'label' ) - +), ( + 'eg.offline.print_receipt', 'gui', 'bool', + oils_i18n_gettext( + 'eg.offline.print_receipt', + 'Offline Print Receipt', + 'cwst', 'label' + ) +), ( + 'eg.offline.strict_barcode', 'gui', 'bool', + oils_i18n_gettext( + 'eg.offline.strict_barcode', + 'Offline Use Strict Barcode', + 'cwst', 'label' + ) +), ( + 'cat.default_bib_marc_template', 'gui', 'string', + oils_i18n_gettext( + 'cat.default_bib_marc_template', + 'Default MARC Template', + 'cwst', 'label' + ) +), ( + 'eg.audio.disable', 'gui', 'bool', + oils_i18n_gettext( + 'eg.audio.disable', + 'Disable Staff Client Notification Audio', + 'cwst', 'label' + ) +), ( + 'eg.search.adv_pane', 'gui', 'string', + oils_i18n_gettext( + 'eg.search.adv_pane', + 'Catalog Advanced Search Default Pane', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.bills_current', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.bills_current', + 'Print Template Context: bills_current', + 'cwst', 'label' + ) +), ( + 'eg.print.template.bills_current', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.bills_current', + 'Print Template: bills_current', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.bills_historical', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.bills_historical', + 'Print Template Context: bills_historical', + 'cwst', 'label' + ) +), ( + 'eg.print.template.bills_historical', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.bills_historical', + 'Print Template: bills_historical', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.bill_payment', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.bill_payment', + 'Print Template Context: bill_payment', + 'cwst', 'label' + ) +), ( + 'eg.print.template.bill_payment', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.bill_payment', + 'Print Template: bill_payment', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.checkin', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.checkin', + 'Print Template Context: checkin', + 'cwst', 'label' + ) +), ( + 'eg.print.template.checkin', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.checkin', + 'Print Template: checkin', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.checkout', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.checkout', + 'Print Template Context: checkout', + 'cwst', 'label' + ) +), ( + 'eg.print.template.checkout', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.checkout', + 'Print Template: checkout', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.hold_transit_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.hold_transit_slip', + 'Print Template Context: hold_transit_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template.hold_transit_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.hold_transit_slip', + 'Print Template: hold_transit_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.hold_shelf_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.hold_shelf_slip', + 'Print Template Context: hold_shelf_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template.hold_shelf_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.hold_shelf_slip', + 'Print Template: hold_shelf_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.holds_for_bib', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.holds_for_bib', + 'Print Template Context: holds_for_bib', + 'cwst', 'label' + ) +), ( + 'eg.print.template.holds_for_bib', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.holds_for_bib', + 'Print Template: holds_for_bib', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.holds_for_patron', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.holds_for_patron', + 'Print Template Context: holds_for_patron', + 'cwst', 'label' + ) +), ( + 'eg.print.template.holds_for_patron', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.holds_for_patron', + 'Print Template: holds_for_patron', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.hold_pull_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.hold_pull_list', + 'Print Template Context: hold_pull_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template.hold_pull_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.hold_pull_list', + 'Print Template: hold_pull_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.hold_shelf_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.hold_shelf_list', + 'Print Template Context: hold_shelf_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template.hold_shelf_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.hold_shelf_list', + 'Print Template: hold_shelf_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.in_house_use_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.in_house_use_list', + 'Print Template Context: in_house_use_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template.in_house_use_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.in_house_use_list', + 'Print Template: in_house_use_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.item_status', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.item_status', + 'Print Template Context: item_status', + 'cwst', 'label' + ) +), ( + 'eg.print.template.item_status', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.item_status', + 'Print Template: item_status', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.items_out', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.items_out', + 'Print Template Context: items_out', + 'cwst', 'label' + ) +), ( + 'eg.print.template.items_out', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.items_out', + 'Print Template: items_out', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.patron_address', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.patron_address', + 'Print Template Context: patron_address', + 'cwst', 'label' + ) +), ( + 'eg.print.template.patron_address', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.patron_address', + 'Print Template: patron_address', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.patron_data', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.patron_data', + 'Print Template Context: patron_data', + 'cwst', 'label' + ) +), ( + 'eg.print.template.patron_data', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.patron_data', + 'Print Template: patron_data', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.patron_note', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.patron_note', + 'Print Template Context: patron_note', + 'cwst', 'label' + ) +), ( + 'eg.print.template.patron_note', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.patron_note', + 'Print Template: patron_note', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.renew', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.renew', + 'Print Template Context: renew', + 'cwst', 'label' + ) +), ( + 'eg.print.template.renew', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.renew', + 'Print Template: renew', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.transit_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.transit_list', + 'Print Template Context: transit_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template.transit_list', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.transit_list', + 'Print Template: transit_list', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.transit_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.transit_slip', + 'Print Template Context: transit_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template.transit_slip', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.transit_slip', + 'Print Template: transit_slip', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.offline_checkout', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.offline_checkout', + 'Print Template Context: offline_checkout', + 'cwst', 'label' + ) +), ( + 'eg.print.template.offline_checkout', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.offline_checkout', + 'Print Template: offline_checkout', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.offline_renew', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.offline_renew', + 'Print Template Context: offline_renew', + 'cwst', 'label' + ) +), ( + 'eg.print.template.offline_renew', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.offline_renew', + 'Print Template: offline_renew', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.offline_checkin', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.offline_checkin', + 'Print Template Context: offline_checkin', + 'cwst', 'label' + ) +), ( + 'eg.print.template.offline_checkin', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.offline_checkin', + 'Print Template: offline_checkin', + 'cwst', 'label' + ) +), ( + 'eg.print.template_context.offline_in_house_use', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template_context.offline_in_house_use', + 'Print Template Context: offline_in_house_use', + 'cwst', 'label' + ) +), ( + 'eg.print.template.offline_in_house_use', 'gui', 'string', + oils_i18n_gettext( + 'eg.print.template.offline_in_house_use', + 'Print Template: offline_in_house_use', + 'cwst', 'label' + ) ); + -- More values with fm_class'es INSERT INTO config.workstation_setting_type (name, grp, datatype, fm_class, label) VALUES ( @@ -493,13 +867,6 @@ VALUES ( ); - -/* -INSERT INTO permission.perm_list (id, code, description) VALUES - (594, 'APPLY_WORKSTATION_SETTING', - oils_i18n_gettext(594, 'APPLY_WORKSTATION_SETTING', 'ppl', 'description')); -*/ - COMMIT; @@ -507,3 +874,4 @@ COMMIT; + diff --git a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js index 7eb8cf0555..72f57a0af1 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js +++ b/Open-ILS/web/js/ui/default/staff/circ/checkin/app.js @@ -89,11 +89,8 @@ function($scope , $q , $window , $location , $timeout , egCore , checkinSvc , eg } // set modifiers from stored preferences - // We know these settings live on the server, so manually batch - // them for speed. - // TODO: once Hatch storage is deprecated, add a getItemBatch function. var snames = modifiers.map(function(m) {return 'eg.circ.checkin.' + m;}); - egCore.hatch.getServerItemBatch(snames).then(function(settings) { + egCore.hatch.getItemBatch(snames).then(function(settings) { angular.forEach(settings, function(val, key) { if (val === true) { var parts = key.split('.') diff --git a/Open-ILS/web/js/ui/default/staff/services/hatch.js b/Open-ILS/web/js/ui/default/staff/services/hatch.js index 4936cab74b..f8df253d70 100644 --- a/Open-ILS/web/js/ui/default/staff/services/hatch.js +++ b/Open-ILS/web/js/ui/default/staff/services/hatch.js @@ -233,6 +233,8 @@ angular.module('egCoreMod') ); } + // TODO: once Hatch is printing-only, should probably store + // this preference on the server. service.usePrinting = function() { return service.getLocalItem('eg.hatch.enable.printing'); } @@ -271,6 +273,46 @@ angular.module('egCoreMod') return deferred.promise; } + // Collect values in batch. + // For server-stored values espeically, this is more efficient + // than a series of one-off calls. + service.getItemBatch = function(keys) { + var browserKeys = []; + var serverKeys = []; + + // To take full advantage of the getServerItemBatch call, + // we have to know in advance which keys to send to the server + // vs those to handle in the browser. + keys.forEach(function(key) { + if (service.keyStoredInBrowser(key)) { + browserKeys.push(key); + } else { + serverKeys.push(key); + } + }); + + var settings = {}; + + var serverPromise = serverKeys.length === 0 ? $q.when() : + service.getServerItemBatch(serverKeys).then(function(values) { + angular.forEach(values, function(val, key) { + settings[key] = val; + }); + }); + + var browserPromises = []; + browserKeys.forEach(function(key) { + browserPromises.push( + service.getBrowserItem(key).then(function(val) { + settings[key] = val; + }) + ); + }); + + return $q.all(browserPromises.concat(serverPromise)) + .then(function() {return settings}); + } + service.getBrowserItem = function(key) { if (service.useSettings()) { if (service.hatchAvailable) { @@ -508,11 +550,11 @@ angular.module('egCoreMod') function() { return foundValues; }, function() {}, function(setting) { - var val = setting.value(); + var val = setting.value; // The server returns null for undefined settings. // Treat as undefined locally for backwards compat. - service.keyCache[setting.name()] = - foundValues[setting.name()] = + service.keyCache[setting.name] = + foundValues[setting.name] = (val === null) ? undefined : val; } ); @@ -678,9 +720,12 @@ angular.module('egCoreMod') // if set, prefix limits the return set to keys starting with 'prefix' service.getKeys = function(prefix) { - if (service.useSettings()) - return service.getRemoteKeys(prefix); - return $q.when(service.getLocalKeys(prefix)); + var promise = service.getServerKeys(prefix); + return service.getBrowserKeys(prefix).then(function(browserKeys) { + return promise.then(function(serverKeys) { + return serverKeys.concat(browserKeys); + }); + }); } service.getRemoteKeys = function(prefix) { @@ -690,18 +735,20 @@ angular.module('egCoreMod') }); } + service.getBrowserKeys = function(prefix) { + if (service.useSettings()) + return service.getRemoteKeys(prefix); + return $q.when(service.getLocalKeys(prefix)); + } + service.getServerKeys = function(prefix) { - var keys = []; - var idx = 0; - service.serverSettings.forEach(function(k) { - // key prefix match test - if (prefix && k.substr(0, prefix.length) != prefix) { - return; - } - keys.push(k); - }); - // these may eventually come from the server, so return a promise. - return $q.when(keys); + if (!service.auth) service.auth = $injector.get('egAuth'); + if (!service.auth.token()) return $q.when({}); + return egNet.request( + 'open-ils.actor', + 'open-ils.actor.settings.staff.applied.names.authoritative.atomic', + service.auth.token(), prefix + ); } service.getLocalKeys = function(prefix) {