LP#1053397 MR holds placement; almost
authorBill Erickson <berick@esilibrary.com>
Thu, 30 Jan 2014 22:22:50 +0000 (17:22 -0500)
committerBill Erickson <berick@esilibrary.com>
Thu, 30 Jan 2014 22:24:31 +0000 (17:24 -0500)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Holds.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm
Open-ILS/src/templates/opac/parts/metarecord_hold_filters.tt2
Open-ILS/src/templates/opac/parts/place_hold.tt2

index 8ba48ab..bb7ed2c 100644 (file)
@@ -94,6 +94,11 @@ sub test_and_create_hold_batch {
 
     foreach (@$target_list) {
         $$params{$target_field} = $_;
+
+        # copy the requested formats from the target->formats map
+        # into the top-level formats attr for each hold
+        $$params{holdable_formats} = $$params{holdable_formats_map}{$_};
+
         my $res;
         ($res) = $self->method_lookup(
             'open-ils.circ.title_hold.is_possible')->run($auth, $params, $override ? $oargs : {});
index 462d9d4..1f8076e 100644 (file)
@@ -778,18 +778,49 @@ sub load_place_hold {
 
     my $type_dispatch = {
         M => sub {
+
+            # target metarecords
             my $mrecs = $e->batch_retrieve_metabib_metarecord([
                 \@targets, 
                 {flesh => 1, flesh_fields => {mmr => ['master_record']}}], 
                 {substream => 1}
             );
 
+            # crad.name which defines the set of metarecord formats
+            my $format_attr = $ctx->{search_cgf}->(
+                name => 'opac.metarecord.holds.format_attr')->[0]->value;
+
             for my $id (@targets) {
                 my ($mr) = grep {$_->id eq $id} @$mrecs;
+
+                # during hold placement submission, the user selects
+                # which of the available formats/langs are acceptiable.
+                # Capture those here as the holdable_formats for the MR hold.
+                my @selected_formats = $cgi->param('metarecord_formats_' . $mr->id);
+                my @selected_langs = $cgi->param('metarecord_langs_' . $mr->id);
+
+                # map the selected attrs into the JSON holdable_formats structure
+                @selected_formats = map {
+                    {_attr => $format_attr, _val => $_} } @selected_formats;
+                @selected_langs = map {
+                    {_attr => 'item_lang', _val => $_} } @selected_langs;
+
+                my $holdable_formats = OpenSRF::Utils::JSON->perl2JSON({
+                    0 => \@selected_formats,
+                    1 => \@selected_langs
+                });
+
+                # TODO: cleanup
+                #warn "MR holdable formats: $holdable_formats\n";
+                #warn "MR langs" . Dumper($self->get_mr_ccvms($mr->id, 'item_lang')) . "\n";
+                #warn "MR formats" . Dumper($self->get_mr_ccvms($mr->id, $format_attr)) . "\n";
+
                 push(@hold_data, $data_filler->({
                     target => $mr, 
                     record => $mr->master_record,
-                    metarecord_attrs => $self->get_mr_ccvms($mr->id)
+                    metarecord_formats => $self->get_mr_ccvms($mr->id, $format_attr),
+                    metarecord_langs => $self->get_mr_ccvms($mr->id, 'item_lang'),
+                    holdable_formats => $holdable_formats
                 }));
             }
         },
@@ -1000,13 +1031,25 @@ sub attempt_hold_placement {
 
     if(@create_targets) {
 
+        # holdable formats may be different for each MR hold.
+        # map each set to the ID of the target.
+        my $holdable_formats = {};
+        if ($hold_type eq 'M') {
+            $holdable_formats->{$_->{target_id}} = 
+                $_->{holdable_formats} for @hold_data;
+            # TODO: cleanup
+            warn "MR Holdable formats " . Dumper($holdable_formats) . "\n";
+        }
+
         my $bses = OpenSRF::AppSession->create('open-ils.circ');
         my $breq = $bses->request( 
             $method, 
             $e->authtoken, 
-            $data_filler->({   patronid => $usr,
+            $data_filler->({   
+                patronid => $usr,
                 pickup_lib => $pickup_lib, 
-                hold_type => $hold_type
+                hold_type => $hold_type,
+                holdable_formats_map => $holdable_formats
             }),
             \@create_targets
         );
@@ -1072,14 +1115,14 @@ sub attempt_hold_placement {
 # fetches the CCVMs IDs representing available languages and formats 
 # for the constituent records of the selected metarecord.  
 sub get_mr_ccvms {
-    my ($self, $mr_id) = @_;
+    my ($self, $mr_id, $attr) = @_;
     my $e = $self->editor;
 
     my $bre_ids = 
         $e->search_metabib_metarecord_source_map({metarecord => $mr_id});
     $bre_ids = [map {$_->source} @$bre_ids];
     
-    my $base_query = {
+    my $query = {
         select => {ccvm => [{column => 'id', transform => 'distinct'}]},
         from => {mraf => {
             ccvm => {
@@ -1088,25 +1131,11 @@ sub get_mr_ccvms {
                 filter => {code => {'=' => {'+mraf' => 'value'}}}
             }
         }},
-        where => {'+mraf' => {id => $bre_ids}}
-    };
-
-    $base_query->{where}->{'+mraf'}->{attr} = 'item_lang';
-    my $langs = $e->json_query($base_query);
-
-    # the attr type used for format selection is configurable
-    delete $base_query->{where}->{'+mraf'}->{attr};
-    $base_query->{from}->{mraf}->{cgf} = {
-        fkey => 'attr',
-        field => 'value',
-        filter => {name => 'opac.metarecord.holds.format_attr'}
+        where => {'+mraf' => {id => $bre_ids, attr => $attr}}
     };
-    my $formats = $e->json_query($base_query);
 
-    return {
-        langs => [map { $_->{id} } @$langs],
-        formats => [map { $_->{id} } @$formats]
-    };
+    my $values = $e->json_query($query);
+    return [map { $_->{id} } @$values];
 }
 
 
index ded56c3..488bbab 100644 (file)
@@ -3,27 +3,9 @@ Draws the format multi-select and the language multi-select for
 limiting the set of desired records for a given metarecord.
 %]
 
-[% BLOCK metarecord_hold_filters_selector;
-  format_ccvms = [];
-  lang_ccvms = [];
-  # some CCVMs have search_labels, some use the value as the label
-  # instead.  Accommodate both.
-  FOR ccvm_id IN metarecord_attrs.formats;
-    ccvm = ctx.get_ccvm(ccvm_id);
-    IF NOT ccvm.search_label; ccvm.search_label(ccvm.value); END;
-    format_ccvms.push(ccvm);
-  END;
-  FOR ccvm_id IN metarecord_attrs.langs;
-    ccvm = ctx.get_ccvm(ccvm_id);
-    IF NOT ccvm.search_label; ccvm.search_label(ccvm.value); END;
-    lang_ccvms.push(ccvm);
-  END;
-%]
-
 <style>
   /* TODO: MOVE ME */
   .metarecord_filters {
-      width: 75%;
       padding: 5px;
       margin-top: 5px;
       border-bottom: 1px solid #333;
@@ -34,19 +16,38 @@ limiting the set of desired records for a given metarecord.
     margin-right: 10px;
   }
   .metarecord_filter_container select {
-    padding: 5px;
+    padding: 2px;
+    width: 13em; /* consistent w/ adv search selectors */
   }
   .metarecord_filter_header {
-    padding: 5px;
+    padding-bottom: 5px;
   }
 </style>
 
+[% BLOCK metarecord_hold_filters_selector;
+  format_ccvms = [];
+  lang_ccvms = [];
+  # some CCVMs have search_labels, some use the value as the label
+  # instead.  Accommodate both, starting with search_label
+  FOR ccvm_id IN hold_data.metarecord_formats;
+    ccvm = ctx.get_ccvm(ccvm_id);
+    CALL ccvm.search_label(ccvm.value) UNLESS ccvm.search_label;
+    format_ccvms.push(ccvm);
+  END;
+  FOR ccvm_id IN hold_data.metarecord_langs;
+    ccvm = ctx.get_ccvm(ccvm_id);
+    CALL ccvm.search_label(ccvm.value) UNLESS ccvm.search_label;
+    lang_ccvms.push(ccvm);
+  END;
+%]
+
 <div class="metarecord_filters">
   <div class="metarecord_filter_container">
     <div class="metarecord_filter_header">
       <div>[% l('Select your desired format(s).') %]</div>
     </div>
-    <select multiple='multiple' name="metarecord_formats">
+    <select multiple='multiple' 
+      name="metarecord_formats_[% hold_data.target.id %]">
       [% FOR ccvm IN format_ccvms.sort('search_label') %]
         <option value="[% ccvm.code %]">
           [% ccvm.search_label | html %]
@@ -60,7 +61,8 @@ limiting the set of desired records for a given metarecord.
     <div class="metarecord_filter_header">
       [% l('Select your desired language(s)') %]
     </div>
-    <select multiple='multiple' name="metarecord_langs">
+    <select multiple='multiple' 
+      name="metarecord_langs_[% hold_data.target.id %]">
       [% FOR lang_ccvm IN lang_ccvms.sort('search_label') %]
         <option value="[% lang_ccvm.code %]">
           [% lang_ccvm.search_label | html %]
index 9209efe..110a3c4 100644 (file)
                         <input type='hidden' name='part' value=''/>
                         [% END %]
                     [% END %]
-                    [% IF hdata.metarecord_attrs.formats.size OR # should this be > 1 also?
-                          hdata.metarecord_attrs.langs.size > 1;
-                        PROCESS metarecord_hold_filters_selector 
-                            metarecord_attrs=hdata.metarecord_attrs;
+                    [% IF hdata.metarecord_formats.size OR # should this be size > 1
+                          hdata.metarecord_langs.size > 1;
+                        PROCESS metarecord_hold_filters_selector hold_data=hdata;
                     END %]
                 </td>
             </tr>