From d8cb6cf045335fa1ee090c187785e0f5c38d4c06 Mon Sep 17 00:00:00 2001 From: senator Date: Tue, 6 Apr 2010 16:40:33 +0000 Subject: [PATCH] Acq: unified search interface for LI, PO, and PL. Usable but not 100% finished Still to come: Paging results (very important with large result sets) Searchable timestamp fields (those don't work yet) Search terms interpreted from URI (to enable returning to search later) Misc PO and PL controls to enable acting on search results ** Bib record searching git-svn-id: svn://svn.open-ils.org/ILS/trunk@16140 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/examples/fm_IDL.xml | 2 +- .../OpenILS/Application/Acq/Financials.pm | 14 +- .../OpenILS/Application/Acq/Search.pm | 56 ++- Open-ILS/web/css/skin/default/acq.css | 17 +- Open-ILS/web/js/dojo/openils/acq/nls/acq.js | 1 + .../js/dojo/openils/widget/AutoFieldWidget.js | 2 +- .../web/js/ui/default/acq/search/unified.js | 445 ++++++++++++++++++ Open-ILS/web/opac/locale/en-US/lang.dtd | 2 + .../templates/default/acq/search/unified.tt2 | 167 +++++++ .../staff_client/chrome/content/main/menu.js | 4 + .../chrome/content/main/menu_frame_menus.xul | 8 +- .../chrome/locale/en-US/offline.properties | 1 + 12 files changed, 687 insertions(+), 32 deletions(-) create mode 100644 Open-ILS/web/js/ui/default/acq/search/unified.js create mode 100644 Open-ILS/web/templates/default/acq/search/unified.tt2 diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index 12ee48392b..bf822c320f 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -5238,7 +5238,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - + diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Financials.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Financials.pm index e669e11c0d..1dcb678628 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Financials.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Financials.pm @@ -899,19 +899,23 @@ sub build_price_summary { sub retrieve_purchase_order_impl { my($e, $po_id, $options) = @_; - # let's just always flesh this if it's there. what the hey. - my $flesh = { - "flesh" => 1, "flesh_fields" => {"acqpo" => ["cancel_reason"]} - }; + my $flesh = {"flesh" => 1, "flesh_fields" => {"acqpo" => []}}; $options ||= {}; + unless ($options->{"no_flesh_cancel_reason"}) { + push @{$flesh->{"flesh_fields"}->{"acqpo"}}, "cancel_reason"; + } if ($options->{"flesh_notes"}) { push @{$flesh->{"flesh_fields"}->{"acqpo"}}, "notes"; } if ($options->{"flesh_provider"}) { push @{$flesh->{"flesh_fields"}->{"acqpo"}}, "provider"; } - my $po = $e->retrieve_acq_purchase_order([$po_id, $flesh]) + + my $args = (@{$flesh->{"flesh_fields"}->{"acqpo"}}) ? + [$po_id, $flesh] : $po_id; + + my $po = $e->retrieve_acq_purchase_order($args) or return $e->event; if($$options{flesh_lineitems}) { diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Search.pm b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Search.pm index 16728b552b..24e1b921c4 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Acq/Search.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Acq/Search.pm @@ -156,37 +156,39 @@ sub gen_au_term { # alias, given names and family name. sub prepare_au_terms { my ($terms, $join_num) = @_; + my @joins = (); + my $nots = 0; $join_num ||= 0; foreach my $conj (qw/-and -or/) { next unless exists $terms->{$conj}; my @new_outer_terms = (); - foreach my $hint_unit (@{$terms->{$conj}}) { + HINT_UNIT: foreach my $hint_unit (@{$terms->{$conj}}) { my $hint = (keys %$hint_unit)[0]; (my $plain_hint = $hint) =~ y/+//d; + if ($hint eq "-not") { + $hint_unit = $hint_unit->{$hint}; + $nots++; + redo HINT_UNIT; + } if (my $links = get_fm_links_by_hint($plain_hint) and $plain_hint ne "acqlia") { my @new_terms = (); - foreach my $pair (@{$hint_unit->{$hint}}) { - my ($attr, $value) = breakdown_term($pair); - if ($links->{$attr} and - $links->{$attr}->{"class"} eq "au") { - push @joins, [$plain_hint, $attr, $join_num]; - push @new_outer_terms, gen_au_term($value, $join_num); - $join_num++; - } else { - push @new_terms, $pair; - } - } - if (@new_terms) { - $hint_unit->{$hint} = [ @new_terms ]; - } else { + my ($attr, $value) = breakdown_term($hint_unit->{$hint}); + if ($links->{$attr} and + $links->{$attr}->{"class"} eq "au") { + push @joins, [$plain_hint, $attr, $join_num]; + my $au_term = gen_au_term($value, $join_num); + $au_term = {"-not" => $au_term} if $nots--; + push @new_outer_terms, $au_term; + $join_num++; delete $hint_unit->{$hint}; } } + $hint_unit = {"-not" => $hint_unit} if $nots--; push @new_outer_terms, $hint_unit if scalar keys %$hint_unit; } $terms->{$conj} = [ @new_outer_terms ]; @@ -203,7 +205,6 @@ sub prepare_terms { foreach my $class (qw/acqpo acqpl jub/) { next if not exists $terms->{$class}; - my $clause = []; $outer_clause->{$conj} = [] unless $outer_clause->{$conj}; foreach my $unit (@{$terms->{$class}}) { my ($k, $v, $fuzzy, $between, $not) = breakdown_term($unit); @@ -218,9 +219,10 @@ sub prepare_terms { next; } - push @$clause, $not ? {"-not" => $term_clause} : $term_clause; + my $clause = {"+" . $class => $term_clause}; + $clause = {"-not" => $clause} if $not; + push @{$outer_clause->{$conj}}, $clause; } - push @{$outer_clause->{$conj}}, {"+" . $class => $clause}; } if ($terms->{"acqlia"}) { @@ -328,12 +330,12 @@ sub unified_search { "from" => { "jub" => { "acqpo" => { - "type" => "left", + "type" => "full", "field" => "id", "fkey" => "purchase_order" }, "acqpl" => { - "type" => "left", + "type" => "full", "field" => "id", "fkey" => "picklist" } @@ -352,6 +354,9 @@ sub unified_search { }; }; + # TODO find instances of fields of type "timestamp" and massage the + # comparison to match search input (which is only at date precision, + # not timestamp). my $offset = add_au_joins($query->{"from"}, prepare_au_terms($and_terms)); add_au_joins($query->{"from"}, prepare_au_terms($or_terms, $offset)); @@ -369,7 +374,16 @@ sub unified_search { } my $results = $e->json_query($query) or return $e->die_event; - $conn->respond($retriever->($e, $_->{"id"}, $options)) foreach (@$results); + if ($options->{"id_list"}) { + foreach (@$results) { + $conn->respond($_->{"id"}) if $_->{"id"}; + } + } else { + foreach (@$results) { + $conn->respond($retriever->($e, $_->{"id"}, $options)) + if $_->{"id"}; + } + } $e->disconnect; undef; } diff --git a/Open-ILS/web/css/skin/default/acq.css b/Open-ILS/web/css/skin/default/acq.css index 1af2109754..024f32dd63 100644 --- a/Open-ILS/web/css/skin/default/acq.css +++ b/Open-ILS/web/css/skin/default/acq.css @@ -195,9 +195,24 @@ span[name="notes_alert_flag"] {color: #c00;font-weight: bold;font-size: 110%;mar border:1px solid #888; } - /* INVOICING */ #oils-acq-invoice-table td { padding: 5px; } #acq-invoice-new-msg { font-weight: bold; margin: 10px;} #acq-invoice-li-details { padding: 10px; font-weight: bold; border: 1px solid #888; margin: 10px; } #acq-invoice-create { margin: 10px; } +#acq-unified-heading { margin-bottom: 10px; } +#acq-unified-heading-actual { float: left; width: 50%; font-size: 120%; font-weight: bold; } +#acq-unified-heading-controls { float: right; width: 50%; text-align: right; } +#acq-unified-form { margin-bottom: 10px; border-bottom: 1px dashed #666; padding-bottom: 10px; } +#acq-unified-form > div { margin: 6px 0; } +option[disabled="disabled"] { font-style: italic; } +#acq-unified-terms-table { width: 100%; } +#acq-unified-terms-table td { padding: 4px 0; } +#acq-unified-add-term { padding-bottom: 20px; } +.acq-unified-option-header { padding-left: 12px; } +.acq-unified-option-regular { padding-left: 24px; } +.acq-unified-terms-selector { width: 20%; } +.acq-unified-terms-widget { width: 60%; } +.acq-unified-terms-match { width: 15%; } +.acq-unified-terms-remove { width: 5%; text-align: right; } +.acq-unified-remover { color: #c00; } diff --git a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js index 0ae9ffcd88..7b7b7a0410 100644 --- a/Open-ILS/web/js/dojo/openils/acq/nls/acq.js +++ b/Open-ILS/web/js/dojo/openils/acq/nls/acq.js @@ -57,4 +57,5 @@ 'CONFIRM_FUNDS_AT_STOP': "One or more of the selected funds has a balance below its stop level.\nYou may not be able to activate purchase orders incorporating these copies.\nContinue?", 'CONFIRM_FUNDS_AT_WARNING': "One or more of the selected funds has a balance below its warning level.\nContinue?", 'INVOICE_ITEM_DETAILS' : "${0}
${1}
${2}.
Estimated Price: $${3}.
Lineitem ID: ${4}
PO: ${5}
Order Date: ${6}", + 'UNNAMED': "Unnamed" } diff --git a/Open-ILS/web/js/dojo/openils/widget/AutoFieldWidget.js b/Open-ILS/web/js/dojo/openils/widget/AutoFieldWidget.js index 25c9919605..838872bcbd 100644 --- a/Open-ILS/web/js/dojo/openils/widget/AutoFieldWidget.js +++ b/Open-ILS/web/js/dojo/openils/widget/AutoFieldWidget.js @@ -494,7 +494,7 @@ if(!dojo._hasResource['openils.widget.AutoFieldWidget']) { } else { this.baseWidgetValue(this.widgetValue); - if(this.idlField.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence && !this.selfReference) + if(this.idlField.name == this.fmIDL.pkey && this.fmIDL.pkey_sequence && (!this.selfReference && !this.noDisablePkey)) this.widget.attr('disabled', true); if(this.disableWidgetTest && this.disableWidgetTest(this.idlField.name, this.fmObject)) this.widget.attr('disabled', true); diff --git a/Open-ILS/web/js/ui/default/acq/search/unified.js b/Open-ILS/web/js/ui/default/acq/search/unified.js new file mode 100644 index 0000000000..4f19542b00 --- /dev/null +++ b/Open-ILS/web/js/ui/default/acq/search/unified.js @@ -0,0 +1,445 @@ +dojo.require("openils.widget.AutoGrid"); +dojo.require("openils.widget.AutoWidget"); +dojo.require("openils.PermaCrud"); +dojo.require("openils.Util"); + +var termSelectorFactory; +var termManager; +var resultManager; +var pcrud = new openils.PermaCrud(); + +/* typing save: add getValue() to all HTML + + + + + + + + + +
+ + + + + + + + + +
+ +
+
+
+ +
+
+ +
+ + + + + + + +[% END %] diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu.js b/Open-ILS/xul/staff_client/chrome/content/main/menu.js index eca544c774..02f5ae4e50 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu.js @@ -691,6 +691,10 @@ main.menu.prototype = { ['oncommand'], function() { open_eg_web_page('acq/picklist/bib_search', 'menu.cmd_acq_bib_search.tab'); } ], + 'cmd_acq_unified_search' : [ + ['oncommand'], + function() { open_eg_web_page('acq/search/unified', 'menu.cmd_acq_unified_search.tab'); } + ], 'cmd_acq_li_search' : [ ['oncommand'], function() { open_eg_web_page('acq/lineitem/search', 'menu.cmd_acq_li_search.tab'); } diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul index bfbc461bf7..2caaa9f622 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul @@ -83,6 +83,7 @@ + @@ -253,13 +254,14 @@ - + + + + - - diff --git a/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties b/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties index 2c41c0a81d..916e15859e 100644 --- a/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties +++ b/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties @@ -222,6 +222,7 @@ menu.cmd_local_admin_cash_reports.tab=Cash Reports menu.cmd_local_admin_transit_list.tab=Transits menu.cmd_acq_view_picklist.tab=Selection Lists menu.cmd_acq_bib_search.tab=Title Search +menu.cmd_acq_unified_search.tab=Acquisitions Search menu.cmd_acq_li_search.tab=Lineitem Search menu.cmd_acq_upload.tab=Load Order Record menu.cmd_acq_new_brief_record.tab=New Brief Record -- 2.43.2