- Basic OPAC display, including attempt at integration with 'legacy' MFHD display
authordbwells <dbwells@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 11 Aug 2010 21:50:25 +0000 (21:50 +0000)
committerdbwells <dbwells@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 11 Aug 2010 21:50:25 +0000 (21:50 +0000)
- Rename some display variables and svr fields to be more generic
- Add textual holdings 'override' code to MFHD display parser
- Support for 'Binding' mode in Items tab
- Barcode prompt when creating new units (either receiving or binding)
- Add Serial service to example configuration files

git-svn-id: svn://svn.open-ils.org/ILS/branches/seials-integration@17178 dcc99617-32d9-48b4-a31d-7c20da2025e4

14 files changed:
Open-ILS/examples/fm_IDL.xml
Open-ILS/examples/opensrf.xml.example
Open-ILS/examples/opensrf_core.xml.example
Open-ILS/src/extras/ils_events.xml
Open-ILS/src/perlmods/OpenILS/Application/Search/Serial.pm
Open-ILS/src/perlmods/OpenILS/Utils/MFHDParser.pm
Open-ILS/web/js/dojo/openils/opac/nls/opac.js
Open-ILS/web/opac/skin/default/js/rdetail.js
Open-ILS/xul/staff_client/server/serial/manage_items.js
Open-ILS/xul/staff_client/server/serial/manage_items.xul
Open-ILS/xul/staff_client/server/serial/manage_subs.js
Open-ILS/xul/staff_client/server/serial/manage_subs.xul
Open-ILS/xul/staff_client/server/serial/sdist_editor.js
Open-ILS/xul/staff_client/server/serial/serctrl_main.xul

index 2dd87c9..9f8e62f 100644 (file)
@@ -2923,15 +2923,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
        <class id="svr" controller="open-ils.cstore" oils_obj:fieldmapper="serial::virtual_record" oils_persist:virtual="true" reporter:label="Serial Virtual Record">
                <fields>
-                       <field name="id" oils_persist:virtual="true" />
+                       <field name="sre_id" oils_persist:virtual="true" />
                        <field name="location" oils_persist:virtual="true" />
                        <field name="owning_lib" oils_persist:virtual="true" />
-                       <field name="holdings" oils_persist:virtual="true" />
-                       <field name="current_holdings" oils_persist:virtual="true" />
-                       <field name="supplements" oils_persist:virtual="true" />
-                       <field name="current_supplements" oils_persist:virtual="true" />
-                       <field name="indexes" oils_persist:virtual="true" />
-                       <field name="current_indexes" oils_persist:virtual="true" />
+                       <field name="basic_holdings" oils_persist:virtual="true" />
+                       <field name="basic_holdings_add" oils_persist:virtual="true" />
+                       <field name="supplement_holdings" oils_persist:virtual="true" />
+                       <field name="supplement_holdings_add" oils_persist:virtual="true" />
+                       <field name="index_holdings" oils_persist:virtual="true" />
+                       <field name="index_holdings_add" oils_persist:virtual="true" />
                        <field name="online" oils_persist:virtual="true" />
                        <field name="missing" oils_persist:virtual="true" />
                        <field name="incomplete" oils_persist:virtual="true" />
index 192e94f..5382c85 100644 (file)
@@ -976,6 +976,26 @@ vim:et:ts=4:sw=4:
                 </app_settings>
             </open-ils.vandelay>
 
+            <open-ils.serial>
+                <keepalive>3</keepalive>
+                <stateless>1</stateless>
+                <language>perl</language>
+                <implementation>OpenILS::Application::Serial</implementation>
+                <max_requests>17</max_requests>
+                <unix_config>
+                    <unix_sock>open-ils.serial_unix.sock</unix_sock>
+                    <unix_pid>open-ils.serial_unix.pid</unix_pid>
+                    <max_requests>1000</max_requests>
+                    <unix_log>open-ils.serial_unix.log</unix_log>
+                    <min_children>5</min_children>
+                    <max_children>15</max_children>
+                    <min_spare_children>3</min_spare_children>
+                    <max_spare_children>5</max_spare_children>
+                </unix_config>
+                <app_settings>
+                </app_settings>
+            </open-ils.serial>
+
         </apps>
     </default>
 
@@ -1016,6 +1036,7 @@ vim:et:ts=4:sw=4:
                 <appname>open-ils.trigger</appname>  
                 <appname>open-ils.fielder</appname>  
                 <appname>open-ils.vandelay</appname>  
+                <appname>open-ils.serial</appname>  
             </activeapps>
         </localhost>
     </hosts>
index 3097ce0..0d803fc 100644 (file)
@@ -33,6 +33,7 @@ Example OpenSRF bootstrap configuration file for Evergreen
           <service>open-ils.search</service>
           <service>open-ils.supercat</service>
           <service>open-ils.vandelay</service>
+          <service>open-ils.serial</service>
         </services>
       </router>
 
index b4cb739..8affbf7 100644 (file)
 
        <!-- ================================================================ -->
 
+    <event code='11000' textcode='SERIAL_SUBSCRIPTION_NOT_EMPTY'>
+        <desc xml:lang="en-US">The subscription still has dependent objects</desc>
+    </event>
+
+    <event code='11001' textcode='SERIAL_CAPTION_AND_PATTERN_HAS_ISSUANCES'>
+        <desc xml:lang="en-US">The caption/pattern still has dependent issuances</desc>
+    </event>
+
+       <!-- ================================================================ -->
+
 </ils_events>
 
 
index ede2706..d1b7700 100644 (file)
@@ -73,40 +73,41 @@ Given a bib record ID, returns a hash of holdings statements
 
 =cut
 
-sub bib_to_mfhd_hash {
-       my ($self, $client, $bib) = @_;
-       
-       my $mfhd_hash;
-
-       # XXX perhaps this? --miker
-#      my $e = OpenILS::Utils::CStoreEditor->new();
-#      my $mfhd = $e->search_serial_record_entry({ record => $bib });
-#      return $u->generate_svr( $mfhd->[0] ) if (ref $mfhd);
-#      return undef;
-
-       my @mfhd = $U->cstorereq( "open-ils.cstore.json_query.atomic", {
-               select  => { sre => 'marc' },
-               from    => 'sre',
-               where   => { record => $bib, deleted => 'f' },
-               distinct => 1
-       });
-       
-       if (!@mfhd or scalar(@mfhd) == 0) {
-               return undef;
-       }
-
-       my $u = OpenILS::Utils::MFHDParser->new();
-       $mfhd_hash = $u->generate_svr( $mfhd[0][0]->{id}, $mfhd[0][0]->{marc}, $mfhd[0][0]->{owning_lib} );
-
-       return $mfhd_hash;
-}
-
-__PACKAGE__->register_method(
-       method  => "bib_to_mfhd_hash",
-       api_name        => "open-ils.search.serial.record.bib_to_mfhd.retrieve",
-       argc            => 1, 
-       note            => "Given a bibliographic record ID, return MFHD holdings"
-);
+# DEFUNCT ?
+#sub bib_to_mfhd_hash {
+#      my ($self, $client, $bib) = @_;
+#      
+#      my $mfhd_hash;
+#
+#      # XXX perhaps this? --miker
+##     my $e = OpenILS::Utils::CStoreEditor->new();
+##     my $mfhd = $e->search_serial_record_entry({ record => $bib });
+##     return $u->generate_svr( $mfhd->[0] ) if (ref $mfhd);
+##     return undef;
+#
+#      my @mfhd = $U->cstorereq( "open-ils.cstore.json_query.atomic", {
+#              select  => { sre => 'marc' },
+#              from    => 'sre',
+#              where   => { record => $bib, deleted => 'f' },
+#              distinct => 1
+#      });
+#      
+#      if (!@mfhd or scalar(@mfhd) == 0) {
+#              return undef;
+#      }
+#
+#      my $u = OpenILS::Utils::MFHDParser->new();
+#      $mfhd_hash = $u->generate_svr( $mfhd[0][0]->{id}, $mfhd[0][0]->{marc}, $mfhd[0][0]->{owning_lib} );
+#
+#      return $mfhd_hash;
+#}
+#
+#__PACKAGE__->register_method(
+#      method  => "bib_to_mfhd_hash",
+#      api_name        => "open-ils.search.serial.record.bib_to_mfhd.retrieve",
+#      argc            => 1, 
+#      note            => "Given a bibliographic record ID, return MFHD holdings"
+#);
 
 sub bib_to_mfhd {
        my ($self, $client, $bib) = @_;
@@ -114,14 +115,61 @@ sub bib_to_mfhd {
        my $mfhd;
 
        my $e = OpenILS::Utils::CStoreEditor->new();
-       my $serials = $e->search_serial_record_entry({ record => $bib, deleted => 'f' });
-       if (!ref $serials) {
+    # TODO: 'deleted' ssub support
+    my $sdists = $e->search_serial_distribution([{ "+ssub" => {"record_entry" => $bib} }, { "flesh" => 1, "flesh_fields" => {'sdist' => [ "record_entry", "basic_summary", "supplement_summary", "index_summary" ]}, "join" => {"ssub" => {}} }]);
+       my $sres = $e->search_serial_record_entry([{ record => $bib, deleted => 'f', "+sdist" => {"id" => undef} }, { "join" => {"sdist" => { 'type' => 'left' }} }]);
+       if (!ref $sres and !ref $sdists) {
                return undef;
        }
 
-       my $u = OpenILS::Utils::MFHDParser->new();
-       foreach (@$serials) {
-               push(@$mfhd, $u->generate_svr($_->id, $_->marc, $_->owning_lib));
+       my $mfhd_parser = OpenILS::Utils::MFHDParser->new();
+       foreach (@$sdists) {
+        my $svr;
+        if (ref $_->record_entry) {
+            $svr = $mfhd_parser->generate_svr($_->record_entry->id, $_->record_entry->marc, $_->record_entry->owning_lib);
+        } else {
+            $svr = Fieldmapper::serial::virtual_record->new;
+            $svr->sre_id(-1);
+            $svr->location(-1); #TODO: location support
+            $svr->owning_lib($_->holding_lib);
+            $svr->basic_holdings([]);
+            $svr->supplement_holdings([]);
+            $svr->index_holdings([]);
+            $svr->basic_holdings_add([]);
+            $svr->supplement_holdings_add([]);
+            $svr->index_holdings_add([]);
+            $svr->online([]);
+            $svr->missing([]);
+            $svr->incomplete([]);
+        }
+        if (ref $_->basic_summary) { #TODO: 'show-generated' boolean on summaries
+            if ($_->basic_summary->generated_coverage) {
+                push(@{$svr->basic_holdings}, $_->basic_summary->generated_coverage);
+            }
+            if ($_->basic_summary->textual_holdings) {
+                push(@{$svr->basic_holdings_add}, $_->basic_summary->textual_holdings);
+            }
+        }
+        if (ref $_->supplement_summary) {
+            if ($_->supplement_summary->generated_coverage) {
+                push(@{$svr->supplement_holdings}, $_->supplement_summary->generated_coverage);
+            }
+            if ($_->supplement_summary->textual_holdings) {
+                push(@{$svr->supplement_holdings_add}, $_->supplement_summary->textual_holdings);
+            }
+        }
+        if (ref $_->index_summary) {
+            if ($_->index_summary->generated_coverage) {
+                push(@{$svr->index_holdings}, $_->index_summary->generated_coverage);
+            }
+            if ($_->index_summary->textual_holdings) {
+                push(@{$svr->index_holdings_add}, $_->index_summary->textual_holdings);
+            }
+        }
+        push(@$mfhd, $svr);
+       }
+       foreach (@$sres) {
+               push(@$mfhd, $mfhd_parser->generate_svr($_->id, $_->marc, $_->owning_lib));
        }
 
        return $mfhd;
index 2e49cc0..7a191dd 100644 (file)
@@ -59,16 +59,16 @@ sub mfhd_to_hash {
     my $marc;
     my $mfhd;
 
-    my $location            = '';
-    my $holdings            = [];
-    my $supplements         = [];
-    my $indexes             = [];
-    my $current_holdings    = [];
-    my $current_supplements = [];
-    my $current_indexes     = [];
-    my $online              = [];    # Laurentian extension to MFHD standard
-    my $missing             = [];    # Laurentian extension to MFHD standard
-    my $incomplete          = [];    # Laurentian extension to MFHD standard
+    my $location                = '';
+    my $basic_holdings          = [];
+    my $supplement_holdings     = [];
+    my $index_holdings          = [];
+    my $basic_holdings_add      = [];
+    my $supplement_holdings_add = [];
+    my $index_holdings_add      = [];
+    my $online                  = [];    # Laurentian extension to MFHD standard
+    my $missing                 = [];    # Laurentian extension to MFHD standard
+    my $incomplete              = [];    # Laurentian extension to MFHD standard
 
     try {
         $marc = MARC::Record->new_from_xml($mfhd_xml);
@@ -108,48 +108,89 @@ sub mfhd_to_hash {
 
     $location =~ s/ -- $//;
 
+    # TODO: for now, we will assume that textual holdings are in addition to the 
+    # computable holdings (that is, they have link IDs greater than the 85X fields)
+    # or that they fully replace the computable holdings (checking for link ID '0').
+    # Eventually this may be handled better by format_holdings() in MFHD.pm
+    my %skip_computable;
     try {
         foreach my $field ($marc->field('866')) {
             my $textual_holdings = $self->format_textual_holdings($field);
             if ($textual_holdings) {
-                push @$holdings, $textual_holdings;
+                push @$basic_holdings_add, $textual_holdings;
+                if ($field->subfield('8') eq '0') {
+                   $skip_computable{'basic'} = 1; # link ID 0 trumps computable fields
+                }
             }
         }
         foreach my $field ($marc->field('867')) {
             my $textual_holdings = $self->format_textual_holdings($field);
             if ($textual_holdings) {
-                push @$supplements, $textual_holdings;
+                push @$supplement_holdings_add, $textual_holdings;
+                if ($field->subfield('8') eq '0') {
+                   $skip_computable{'supplement'} = 1; # link ID 0 trumps computable fields
+                }
             }
         }
         foreach my $field ($marc->field('868')) {
             my $textual_holdings = $self->format_textual_holdings($field);
             if ($textual_holdings) {
-                push @$indexes, $textual_holdings;
+                push @$index_holdings_add, $textual_holdings;
+                if ($field->subfield('8') eq '0') {
+                   $skip_computable{'index'} = 1; # link ID 0 trumps computable fields
+                }
             }
         }
 
-        foreach my $cap_id ($mfhd->caption_link_ids('853')) {
-            my @curr_holdings = $mfhd->holdings('863', $cap_id);
-            next unless scalar @curr_holdings;
-            foreach (@curr_holdings) {
-                push @$current_holdings, $_->format();
+        if (!exists($skip_computable{'basic'})) {
+            foreach my $cap_id ($mfhd->caption_link_ids('853')) {
+                my @holdings = $mfhd->holdings('863', $cap_id);
+                next unless scalar @holdings;
+                foreach (@holdings) {
+                    push @$basic_holdings, $_->format();
+                }
             }
+            if (!@$basic_holdings) { # no computed holdings found
+                $basic_holdings = $basic_holdings_add;
+                $basic_holdings_add = [];
+            }
+        } else { # textual are non additional, but primary
+            $basic_holdings = $basic_holdings_add;
+            $basic_holdings_add = [];
         }
 
-        foreach my $cap_id ($mfhd->caption_link_ids('854')) {
-            my @curr_supplements = $mfhd->holdings('864', $cap_id);
-            next unless scalar @curr_supplements;
-            foreach (@curr_supplements) {
-                push @$current_supplements, $_->format();
+        if (!exists($skip_computable{'supplement'})) {
+            foreach my $cap_id ($mfhd->caption_link_ids('854')) {
+                my @supplements = $mfhd->holdings('864', $cap_id);
+                next unless scalar @supplements;
+                foreach (@supplements) {
+                    push @$supplement_holdings, $_->format();
+                }
+            }
+            if (!@$supplement_holdings) { # no computed holdings found
+                $supplement_holdings = $supplement_holdings_add;
+                $supplement_holdings_add = [];
             }
+        } else { # textual are non additional, but primary
+            $supplement_holdings = $supplement_holdings_add;
+            $supplement_holdings_add = [];
         }
 
-        foreach my $cap_id ($mfhd->caption_link_ids('855')) {
-            my @curr_indexes = $mfhd->holdings('865', $cap_id);
-            next unless scalar @curr_indexes;
-            foreach (@curr_indexes) {
-                push @$current_indexes, $_->format();
+        if (!exists($skip_computable{'index'})) {
+            foreach my $cap_id ($mfhd->caption_link_ids('855')) {
+                my @indexes = $mfhd->holdings('865', $cap_id);
+                next unless scalar @indexes;
+                foreach (@indexes) {
+                    push @$index_holdings, $_->format();
+                }
+            }
+            if (!@$index_holdings) { # no computed holdings found
+                $index_holdings = $index_holdings_add;
+                $index_holdings_add = [];
             }
+        } else { # textual are non additional, but primary
+            $index_holdings = $index_holdings_add;
+            $index_holdings_add = [];
         }
 
         # Laurentian extensions
@@ -179,15 +220,16 @@ sub mfhd_to_hash {
     };
 
     return {
-        location            => $location,
-        holdings            => $holdings,
-        current_holdings    => $current_holdings,
-        supplements         => $supplements,
-        current_supplements => $current_supplements,
-        indexes             => $indexes,
-        current_indexes     => $current_indexes,
-        missing             => $missing,
-        incomplete          => $incomplete,
+        location                => $location,
+        basic_holdings          => $basic_holdings,
+        basic_holdings_add      => $basic_holdings_add,
+        supplement_holdings     => $supplement_holdings,
+        supplement_holdings_add => $supplement_holdings_add,
+        index_holdings          => $index_holdings,
+        index_holdings_add      => $index_holdings_add,
+        missing                 => $missing,
+        incomplete              => $incomplete,
+        online                  => $online
     };
 }
 
@@ -203,15 +245,15 @@ Initialize the serial virtual record (svr) instance
 
 sub init_holdings_virtual_record {
     my $record = Fieldmapper::serial::virtual_record->new;
-    $record->id();
+    $record->sre_id();
     $record->location();
     $record->owning_lib();
-    $record->holdings([]);
-    $record->current_holdings([]);
-    $record->supplements([]);
-    $record->current_supplements([]);
-    $record->indexes([]);
-    $record->current_indexes([]);
+    $record->basic_holdings([]);
+    $record->basic_holdings_add([]);
+    $record->supplement_holdings([]);
+    $record->supplement_holdings_add([]);
+    $record->index_holdings([]);
+    $record->index_holdings_add([]);
     $record->online([]);
     $record->missing([]);
     $record->incomplete([]);
@@ -238,7 +280,7 @@ sub generate_svr {
     my $record   = init_holdings_virtual_record();
     my $holdings = $self->mfhd_to_hash($mfhd);
 
-    $record->id($id);
+    $record->sre_id($id);
     $record->owning_lib($owning_lib);
 
     if (!$holdings) {
@@ -246,12 +288,12 @@ sub generate_svr {
     }
 
     $record->location($holdings->{location});
-    $record->holdings($holdings->{holdings});
-    $record->current_holdings($holdings->{current_holdings});
-    $record->supplements($holdings->{supplements});
-    $record->current_supplements($holdings->{current_supplements});
-    $record->indexes($holdings->{indexes});
-    $record->current_indexes($holdings->{current_indexes});
+    $record->basic_holdings($holdings->{basic_holdings});
+    $record->basic_holdings_add($holdings->{basic_holdings_add});
+    $record->supplement_holdings($holdings->{supplement_holdings});
+    $record->supplement_holdings_add($holdings->{supplement_holdings_add});
+    $record->index_holdings($holdings->{index_holdings});
+    $record->index_holdings_add($holdings->{index_holdings_add});
     $record->online($holdings->{online});
     $record->missing($holdings->{missing});
     $record->incomplete($holdings->{incomplete});
index 000d879..7d515bf 100644 (file)
        "EDIT_MFHD_RECORD": "Edit Record",
        "EDIT_MFHD_MENU": "Edit Holdings",
        "EDIT_PROPERTIES": "Edit Propeties",
-       "HOLDINGS": "Previous volumes",
-       "INDEXES": "Previous indexes",
+       "BASIC_HOLDINGS": "Volumes",
+       "BASIC_HOLDINGS_ADD": "Additional Volume Information",
+       "INDEX_HOLDINGS": "Indexes",
+       "INDEX_HOLDINGS_ADD": "Additional Index Information",
        "CURRENT_HOLDINGS": "Current volume",
        "CURRENT_INDEXES": "Current indexes",
        "CURRENT_SUPPLEMENTS": "Current supplements",
@@ -28,5 +30,6 @@
        "MISSING_VOLUMES": "Missing volumes",
        "ONLINE_VOLUMES": "Online volumes",
        "SAVE_MFHD_LABEL": "Save MFHD",
-       "SUPPLEMENTS": "Previous supplements"
+       "SUPPLEMENT_HOLDINGS": "Supplements",
+       "SUPPLEMENT_HOLDINGS_ADD": "Additional Supplement Information"
 }
index 0713e97..de6568c 100644 (file)
@@ -262,19 +262,19 @@ function _holdingsDrawMFHD(holdings, entryNum) {
                }
         }
 
-       var hh = holdings.holdings();
-       var hch = holdings.current_holdings();
-       var hs = holdings.supplements();
-       var hcs = holdings.current_supplements();
-       var hi = holdings.indexes();
-       var hci = holdings.current_indexes();
+       var hb = holdings.basic_holdings();
+       var hba = holdings.basic_holdings_add();
+       var hs = holdings.supplement_holdings();
+       var hsa = holdings.supplement_holdings_add();
+       var hi = holdings.index_holdings();
+       var hia = holdings.index_holdings_add();
        var ho = holdings.online();
        var hm = holdings.missing();
        var hinc = holdings.incomplete();
        var hloc = holdings.location() || 'MFHD';
 
-       if (    hh.length == 0 && hch.length == 0 && hs.length == 0 &&
-               hcs.length == 0 && hi.length == 0 && hci.length == 0 &&
+       if (    hb.length == 0 && hba.length == 0 && hs.length == 0 &&
+               hsa.length == 0 && hi.length == 0 && hia.length == 0 &&
                ho.length == 0 && hm.length == 0 && hinc.length == 0
        ) {
 
@@ -284,14 +284,14 @@ function _holdingsDrawMFHD(holdings, entryNum) {
                         * record is likely empty or corrupt. This gives cataloguers a
                         * chance to add holdings or correct the record
                         */
-                       hh = 'PLACEHOLDER';
+                       hb = ['PLACEHOLDER'];
                } else {
                        return null;
                }
        }
 
        // Show entryNum + 1 in staff client for better menu correlation
-       // Maybe this should be holdings.id() instead? (which could get long after time)
+       // Maybe this should be holdings.sre_id() instead? (which could get long after time)
        var entryNumString = '';
        if (isXUL()) {
                var entryNumInc = entryNum + 1;
@@ -303,31 +303,31 @@ function _holdingsDrawMFHD(holdings, entryNum) {
                "</caption><tbody id='rdetail_holdings_tbody_" + entryNum +
                "'></tbody></table>", "rdetail_details_table", "after"
        );
-       if (hh.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.HOLDINGS, hh); }
-       if (hch.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_HOLDINGS, hch); }
-       if (hs.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.SUPPLEMENTS, hs); }
-       if (hcs.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_SUPPLEMENTS, hcs); }
-       if (hi.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INDEXES, hi); }
-       if (hci.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_INDEXES, hci); }
+       if (hb.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.BASIC_HOLDINGS, hb); }
+       if (hba.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.BASIC_HOLDINGS_ADD, hba); }
+       if (hs.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.SUPPLEMENT_HOLDINGS, hs); }
+       if (hsa.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.SUPPLEMENT_HOLDINGS_ADD, hsa); }
+       if (hi.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INDEX_HOLDINGS, hi); }
+       if (hia.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INDEX_HOLDINGS_ADD, hia); }
        if (ho.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.ONLINE_VOLUMES, ho); }
        if (hm.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.MISSING_VOLUMES, hm); }
        if (hinc.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INCOMPLETE_VOLUMES, hinc); }
 
        if (isXUL()) {
-               mfhdDetails.push({ 'id' : holdings.id(), 'label' : hloc, 'entryNum' : entryNum, 'owning_lib' : holdings.owning_lib() });
+               mfhdDetails.push({ 'id' : holdings.sre_id(), 'label' : hloc, 'entryNum' : entryNum, 'owning_lib' : holdings.owning_lib() });
                dojo.require('openils.Event');
                dojo.require('openils.PermaCrud');
                var mfhd_edit = new dijit.Menu({});
-               new dijit.MenuItem({onClick: function(){loadMarcEditor(holdings.id())}, label:opac_strings.EDIT_MFHD_RECORD}).placeAt(mfhd_edit, "first");
+               new dijit.MenuItem({onClick: function(){loadMarcEditor(holdings.sre_id())}, label:opac_strings.EDIT_MFHD_RECORD}).placeAt(mfhd_edit, "first");
                new dijit.MenuItem({onClick:function(){
                        var pcrud = new openils.PermaCrud({"authtoken": G.user.session});
-                       var mfhd_rec = pcrud.retrieve("sre", holdings.id());
+                       var mfhd_rec = pcrud.retrieve("sre", holdings.sre_id());
                        if (mfhd_rec) {
                                pcrud.eliminate(mfhd_rec);
-                               alert(dojo.string.substitute(opac_strings.DELETED_MFHD_RECORD, [holdings.id()]));
+                               alert(dojo.string.substitute(opac_strings.DELETED_MFHD_RECORD, [holdings.sre_id()]));
                        }
                }, label:opac_strings.DELETE_MFHD}).placeAt(mfhd_edit, "last");
-               // new dijit.MenuItem({onClick:function(){alert("Edit properties " + holdings.id());}, label:opac_strings.EDIT_PROPERTIES}).placeAt(mfhd_edit, "last");
+               // new dijit.MenuItem({onClick:function(){alert("Edit properties " + holdings.sre_id());}, label:opac_strings.EDIT_PROPERTIES}).placeAt(mfhd_edit, "last");
                var mfhd_mb = new dijit.form.DropDownButton({dropDown: mfhd_edit, label:opac_strings.EDIT_MFHD_MENU, style:"float:right"});
                mfhd_mb.placeAt("mfhdHoldingsCaption" + entryNum, "last");
                mfhd_edit.startup();
index 1177e67..7e217ac 100644 (file)
@@ -10,6 +10,7 @@ serial.manage_items = function (params) {
        JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
 
     this.current_sunit_id = -1; //default to **AUTO**
+    this.mode = 'receive';
 
 }
 
@@ -80,9 +81,8 @@ serial.manage_items.prototype = {
             ml.addEventListener(
                 'command',
                 function(ev) {
-                    if (document.getElementById('serial_item_refresh_button')) document.getElementById('serial_item_refresh_button').focus();
-                    JSAN.use('util.file'); var file = new util.file('serial_items_prefs.'+obj.data.server_unadorned);
-                    util.widgets.save_attributes(file, { 'serial_item_lib_menu' : [ 'value' ], 'mode_receive' : [ 'selected' ], 'mode_bind' : [ 'selected' ], 'serial_manage_items_show_all' : [ 'checked' ] });
+                    //if (document.getElementById('serial_item_refresh_button')) document.getElementById('serial_item_refresh_button').focus();
+                    obj.save_settings();
                     // get latest sdist id list based on library drowdown
                     obj.set_sdist_ids();
                     obj.refresh_list('main');
@@ -90,6 +90,7 @@ serial.manage_items.prototype = {
                 },
                 false
             );
+
         } else {
             throw(document.getElementById('catStrings').getString('staff.cat.copy_browser.missing_library') + '\n');
         }
@@ -100,6 +101,13 @@ serial.manage_items.prototype = {
             ml.value = org.id();
             ml.setAttribute('value',ml.value);
         }
+        
+        // deal with mode radio selectedIndex, as load_attributes is setting a "read-only" value
+        if ($('mode_receive').getAttribute('selected')) {
+            $('serial_manage_items_mode').selectedIndex = 0;
+        } else {
+            $('serial_manage_items_mode').selectedIndex = 1;
+        }
 
         // setup recent sunits list
         var recent_sunits_file = new util.file('serial_items_recent_sunits_'+obj.docid+'.'+obj.data.server_unadorned);
@@ -125,6 +133,30 @@ serial.manage_items.prototype = {
         obj.set_sdist_ids();
                obj.init_lists();
 
+        var mode_radio_group = $('serial_manage_items_mode');
+        obj.set_mode(mode_radio_group.selectedItem.id.substr(5));
+        mode_radio_group.addEventListener(
+            'command',
+            function(ev) {
+                obj.save_settings();
+                var mode = ev.target.id.substr(5); //strip out 'mode_'
+                obj.set_mode(mode);
+                obj.refresh_list('main');
+                obj.refresh_list('workarea');
+            },
+            false
+        );
+        $('serial_manage_items_show_all').addEventListener(
+            'command',
+            function(ev) {
+                obj.save_settings();
+                obj.set_mode();
+                obj.refresh_list('main');
+                obj.refresh_list('workarea');
+            },
+            false
+        );
+
                JSAN.use('util.controller'); obj.controller = new util.controller();
                obj.controller.init(
                        {
@@ -242,6 +274,7 @@ serial.manage_items.prototype = {
                                 var sstr_id = target.getAttribute('sstr_id');
                                 obj.set_sunit(sunit_id, label, sdist_id, sstr_id);
                                 obj.save_sunit(sunit_id, label, sdist_id, sstr_id);
+                                if (obj.mode == 'bind') obj.refresh_list('workarea');
                             } catch(E) {
                                 obj.error.standard_unexpected_error_alert('cmd_set_sunit failed!',E);
                             }
@@ -251,6 +284,7 @@ serial.manage_items.prototype = {
                         ['command'],
                         function() {
                             obj.set_other_sunit();
+                            if (obj.mode == 'bind') obj.refresh_list('workarea');
                         }
                     ],
                     'cmd_predict_items' : [
@@ -273,14 +307,61 @@ serial.manage_items.prototype = {
                                         }
                                     );
 
+                                var method; var success_label;
+                                if (obj.mode == 'receive') {
+                                    method = 'open-ils.serial.receive_items';
+                                    success_label = 'received';
+                                } else { // bind mode
+                                    method = 'open-ils.serial.bind_items';
+                                    success_label = 'bound';
+                                } 
+
+                                // deal with barcodes for *NEW* units
+                                var barcodes = {};
+                                if (obj.current_sunit_id < 0) { // **AUTO** or **NEW** units
+                                    new_unit_barcode = '';
+                                    for (var i = 0; i < list.length; i++) {
+                                        var item = list[i];
+                                        if (new_unit_barcode) {
+                                            barcodes[item.id()] = new_unit_barcode;
+                                            continue;
+                                        }
+                                        var prompt_text;
+                                        if (obj.current_sunit_id == -1) {
+                                            prompt_text = 'Please enter a barcode for '+item.issuance().label()+ ' from Distribution: '+item.stream().distribution().label()+'/'+item.stream().id()+':';
+                                        } else { // must be -2
+                                            prompt_text = 'Please enter a barcode for new unit:';
+                                        }
+                                        var barcode = window.prompt(prompt_text,
+                                            '',
+                                            'Unit Barcode Prompt');
+                                        barcode = String( barcode ).replace(/\s/g,'');
+                                        /* Casting a possibly null input value to a String turns it into "null" */
+                                        if (!barcode || barcode == 'null') {
+                                            alert('Invalid barcode entered, defaulting to system-generated.');
+                                            barcode = 'auto';
+                                        }
+
+                                        var test = obj.network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ barcode ]);
+                                        if (typeof test.ilsevent == 'undefined') {
+                                            alert('Another copy has barcode "' + barcode + '", defaulting to system-generated.');
+                                            barcode = 'auto';
+                                        }
+                                        barcodes[item.id()] = barcode;
+                                        if (obj.current_sunit_id == -2) {
+                                            new_unit_barcode = barcode;
+                                        }
+                                    }
+                                }
+
                                 var robj = obj.network.request(
                                             'open-ils.serial',
-                                            'open-ils.serial.receive_items',
-                                            [ ses(), list ]
+                                            method,
+                                            [ ses(), list, barcodes ]
                                         );
                                 if (typeof robj.ilsevent != 'undefined') throw(robj); //TODO: catch for override
 
-                                alert('Successfully received '+robj.num_items_received+' item(s)');
+                                alert('Successfully '+success_label+' '+robj.num_items+' item(s)');
 
                                 if (obj.current_sunit_id == -2) {
                                     obj.current_sunit_id = robj.new_unit_id;
@@ -319,7 +400,7 @@ serial.manage_items.prototype = {
 
                     'cmd_items_print' : [ ['command'], function() { obj.items_print(obj.selected_list); } ],
                                        'cmd_items_export' : [ ['command'], function() { obj.items_export(obj.selected_list); } ],
-                                       'cmd_refresh_list' : [ ['command'], function() { obj.refresh_list('main'); obj.refresh_list('workarea'); } ]
+                                       'cmd_refresh_list' : [ ['command'], function() { obj.set_sdist_ids(); obj.refresh_list('main'); obj.refresh_list('workarea'); } ]
                                }
                        }
                );
@@ -472,6 +553,50 @@ serial.manage_items.prototype = {
                }
        },
 
+       'set_mode' : function(mode) {
+               var obj = this;
+
+        if (!mode) {
+            mode = obj.mode;
+        } else {
+            obj.mode = mode;
+        }
+
+        if (mode == 'receive') {
+            $('serial_workarea_mode_label').value = 'Recently Received';
+            if ($('serial_manage_items_show_all').checked) {
+                obj.lists.main.sitem_retrieve_params = {};
+            } else {
+                obj.lists.main.sitem_retrieve_params = {'date_received' : null };
+            }
+            obj.lists.main.sitem_extra_params ={'order_by' : {'sitem' : 'date_expected ASC, stream ASC'}};
+
+            obj.lists.workarea.sitem_retrieve_params = {'date_received' : {"!=" : null}};
+            obj.lists.workarea.sitem_extra_params ={'order_by' : {'sitem' : 'date_received DESC'}, 'limit' : 30};
+        } else { // bind mode
+            $('serial_workarea_mode_label').value = 'Bound Items in Current Working Unit';
+            if ($('serial_manage_items_show_all').checked) {
+                obj.lists.main.sitem_retrieve_params = {};
+            } else {
+                obj.lists.main.sitem_retrieve_params = {'date_received' : {'!=' : null}, 'status' : {'!=' : 'Bindery'} };
+            }
+            obj.lists.main.sitem_extra_params ={'order_by' : {'sitem' : 'date_expected ASC, stream ASC'}};
+
+            obj.lists.workarea.sitem_retrieve_params = {'status' : 'Bindery'}; // unit set dynamically in 'retrieve'
+            obj.lists.workarea.sitem_extra_params ={'order_by' : {'sitem' : 'date_received DESC'}};
+
+            // default to **NEW UNIT**
+            obj.set_sunit(-2, 'New Unit', '', '');
+        }
+    },
+
+       'save_settings' : function() {
+               var obj = this;
+
+        JSAN.use('util.file'); var file = new util.file('serial_items_prefs.'+obj.data.server_unadorned);
+        util.widgets.save_attributes(file, { 'serial_item_lib_menu' : [ 'value' ], 'mode_receive' : [ 'selected' ], 'mode_bind' : [ 'selected' ], 'serial_manage_items_show_all' : [ 'checked' ] });
+    },
+
        'init_lists' : function() {
                var obj = this;
 
@@ -540,12 +665,6 @@ serial.manage_items.prototype = {
                                }
                        }
                );
-        if (document.getElementById('serial_manage_items_show_all').checked) {
-            obj.lists.main.sitem_retrieve_params = {};
-        } else {
-            obj.lists.main.sitem_retrieve_params = {'date_received' : null };
-        }
-        obj.lists.main.sitem_extra_params ={'order_by' : {'sitem' : 'date_expected ASC, stream ASC'}};
 
         obj.lists.workarea = new util.list('workarea_tree');
                obj.lists.workarea.init(
@@ -574,21 +693,11 @@ serial.manage_items.prototype = {
                                }
                        }
                );
-        obj.lists.workarea.sitem_retrieve_params = {'date_received' : {"!=" : null}};
-        obj.lists.workarea.sitem_extra_params ={'order_by' : {'sitem' : 'date_received DESC'}, 'limit' : 30};
     },
 
        'refresh_list' : function(list_name) {
         var obj = this;
 
-        // TODO: make this change on the checkbox command event?
-        if (list_name == 'main') {
-            if (document.getElementById('serial_manage_items_show_all').checked) {
-                delete obj.lists.main.sitem_retrieve_params.date_received;
-            } else {
-                obj.lists.main.sitem_retrieve_params.date_received = null;
-            }
-        }
         //TODO Optimize this?
         obj.retrieve(list_name);
     },
@@ -597,6 +706,8 @@ serial.manage_items.prototype = {
                var obj = this;
         var list = obj.lists[list_name];
         
+               list.clear();
+
         if (!obj.sdist_ids.length) { // no sdists to retrieve items for
             return;
         }
@@ -604,6 +715,11 @@ serial.manage_items.prototype = {
         var rparams = list.sitem_retrieve_params;
         var robj;
         rparams['+sstr'] = { "distribution" : obj.sdist_ids };
+
+        if (obj.mode == 'bind' && list_name == 'workarea') {
+             rparams['unit'] = obj.current_sunit_id;
+        }
+
         var other_params = list.sitem_extra_params;
         other_params.join = 'sstr';
 
@@ -611,17 +727,14 @@ serial.manage_items.prototype = {
             'FM_SITEM_ID_LIST',
             [ ses(), rparams, other_params ]
         );
-        if (typeof robj.ilsevent!='undefined') {
-            obj.error.standard_unexpected_error_alert('Failed to retrieve serial item ID list',E);
-        }
         if (!robj) {
             robj = [];
+        } else if (typeof robj.ilsevent!='undefined') {
+            obj.error.standard_unexpected_error_alert('Failed to retrieve serial item ID list',E);
         } else if (!robj.length) {
             robj = [robj];
         }
 
-               list.clear();
-
         for (i = 0; i < robj.length; i++) {
             list.append( { 'row' : { 'my' : { 'sitem_id' : robj[i] } }, 'to_bottom' : true, 'no_auto_select' : true } );
         }
index 5cd6baa..c10c436 100644 (file)
@@ -51,6 +51,7 @@ vim:noet:sw=4:ts=4:
             <button id="refresh_button" label="&staff.cat.copy_browser.holdings_maintenance.refresh_button.label;" command="cmd_refresh_list" />
             <spacer flex="1"/>
             <menubar>
+                <!--
                 <menu label="Actions for this Serial Control" accesskey="C">
                     <menupopup>
                         <menuitem command="cmd_predict_items" label="Predict Items"/>
@@ -58,6 +59,7 @@ vim:noet:sw=4:ts=4:
                         <menuitem command="cmd_edit_mfhd" label="Edit MFHD Record"/>
                     </menupopup>
                 </menu>
+                -->
                 <menu label="&staff.cat.copy_browser.holdings_maintenance.actions.label;" accesskey="&staff.cat.copy_browser.holdings_maintenance.actions.accesskey;">
                     <menupopup>
                         <menuitem command="cmd_edit_items" label="Edit Item Attributes" accesskey="&staff.cat.copy_browser.actions.cmd_edit_items.accesskey;"/>
@@ -84,7 +86,7 @@ vim:noet:sw=4:ts=4:
         <splitter state="open" collapse="after" resizebefore="closest" resizeafter="farthest"/>
         <hbox align="center">
             <label style="font-weight: bold" value="Showing: "/>
-            <label id="serial_workarea_type_label" value="Recently Received"/>
+            <label id="serial_workarea_mode_label" value="Recently Received"/>
             <spacer flex="1"/>
             <button label="Receive/Move Selected &#8595;" command="cmd_receive_items"/>
         </hbox>
index 5ac3117..307cc49 100644 (file)
@@ -188,6 +188,7 @@ serial.manage_subs.prototype = {
                             function() {
                                 try {
                                     var list = obj.ids_from_sel_list('ssub');
+                                    if (list.length == 0) list = obj.ids_from_sel_list('scap-group');
                                     if (list.length == 0) return;
 
                                     /*TODO: permission check?
@@ -225,6 +226,7 @@ serial.manage_subs.prototype = {
                             function() {
                                 try {
                                     var list = obj.ids_from_sel_list('ssub');
+                                    if (list.length == 0) list = obj.ids_from_sel_list('siss-group');
                                     if (list.length == 0) return;
 
                                     /*TODO: permission check?
@@ -954,6 +956,8 @@ serial.manage_subs.prototype = {
 
             JSAN.use('util.exec'); var exec = new util.exec(20); exec.timer(obj.funcs,100);
 
+            obj.toggle_actions(); // disable menus initially
+
         } catch(E) {
             this.error.standard_unexpected_error_alert('serial/manage_subs.init: ',E);
         }
@@ -1527,7 +1531,7 @@ serial.manage_subs.prototype = {
                 'to_bottom' : true,
                 'no_auto_select' : true,
             };
-            data['row']['my'][type] = item;
+            data['row']['my'][type] = item; // TODO: future optimization: get only the IDs of these leaves, then fetch the full row in 'retrieve_row'
             var nparams = obj.list.append(data);
             var node = nparams.my_node;
             obj.map_tree[ type + '_' + item.id() ] =  node;
index c7e7f24..f2212a1 100644 (file)
@@ -32,8 +32,7 @@ vim:noet:sw=4:ts=4:
                                 JSAN.errorLevel = "die"; // none, warn, or die
                                 JSAN.addRepository('/xul/server/');
                                 JSAN.use('util.error'); g.error = new util.error();
-                                g.error.sdump('D_TRACE','my_init() for serial/manage_subs.xul');
-                                //JSAN.use('serial2.init');
+                                g.error.sdump('D_TRACE','manage_subs_init() for serial/manage_subs.xul');
                                 JSAN.use('serial.manage_subs'); g.manage_subs = new serial.manage_subs();
 
                                 g.manage_subs.init( { 'docid' : xul_param('docid') } );
@@ -55,7 +54,9 @@ vim:noet:sw=4:ts=4:
                         <menuitem command="cmd_add_sdist" label="Add Distribution"/>
                         <menuitem command="cmd_add_siss" label="Add Issuance"/>
                         <menuitem command="cmd_add_scap" label="Add Caption/Pattern"/>
+                        <menuseparator/>
                         <menuitem command="cmd_make_predictions" label="Make Predictions"/>
+                        <menuseparator/>
                         <menuitem command="cmd_delete_ssub" label="Delete Subscription"/>
                         <menuitem command="cmd_delete_sdist" label="Delete Distribution"/>
                         <menuitem command="cmd_delete_siss" label="Delete Issuance"/>
@@ -78,7 +79,9 @@ vim:noet:sw=4:ts=4:
                                         <menuitem command="cmd_add_sdist" label="Add Distribution"/>
                                         <menuitem command="cmd_add_siss" label="Add Issuance"/>
                                         <menuitem command="cmd_add_scap" label="Add Caption/Pattern"/>
+                                        <menuseparator/>
                                         <menuitem command="cmd_make_predictions" label="Make Predictions"/>
+                                        <menuseparator/>
                                         <menuitem command="cmd_delete_ssub" label="Delete Subscription"/>
                                         <menuitem command="cmd_delete_sdist" label="Delete Distribution"/>
                                         <menuitem command="cmd_delete_siss" label="Delete Issuance"/>
index 490947f..c2c838d 100644 (file)
@@ -314,25 +314,15 @@ serial.sdist_editor.prototype = {
             }
 
             // return cached version if we have it
+            // TODO: clear cache on holding_lib change? (cannot remember how to reproduce this bug)
             if (obj.acn_lists[lib_id]) {
                 return obj.acn_lists[lib_id];
             }
 
-            /* we only show this list if dealing with one org_unit, default to first sdist*/
-            var my_sre = obj.network.request(
-                'open-ils.pcrud',
-                'open-ils.pcrud.retrieve.sre',
-                [ ses(), obj.sdists[0].record_entry() ]
-            );
-
-            if (!my_sre) {
-                return [];
-            }
-
             var acn_list = obj.network.request(
                 'open-ils.pcrud',
                 'open-ils.pcrud.search.acn',
-                [ ses(), {"record" : my_sre.record(), "owning_lib" : lib_id, "deleted" : 'f' }, {"order_by" : {"acn" : "label"} } ]
+                [ ses(), {"record" : obj.docid, "owning_lib" : lib_id, "deleted" : 'f' }, {"order_by" : {"acn" : "label"} } ]
             );
 
             if (!acn_list) {
index 7c595f6..0d9b393 100644 (file)
@@ -62,11 +62,13 @@ vim:noet:sw=4:ts=4:
         <command id="cmd_make_predictions"/>
         <command id="cmd_mark_library"/>
         <command id="cmd_mark_subscription"/>
-               <!--<command id="cmd_predict_items"/>-->
+               <command id="cmd_predict_items"/>
                <command id="cmd_print_spine_labels"/>
                <command id="cmd_receive_items"/>
                <command id="cmd_refresh_list"/>
                <command id="cmd_replace_barcode"/>
+        <command id="cmd_set_sunit" />
+        <command id="cmd_set_other_sunit" />
         <command id="cmd_show_all_libs" />
         <command id="cmd_show_libs_with_distributions" />
         <command id="cmd_show_my_libs" />
@@ -99,21 +101,21 @@ vim:noet:sw=4:ts=4:
        </popupset> -->
 
 <!--   <groupbox flex="1" class="my_overflow"> -->
-        <tabbox id="serial_tabbox" flex="1">
+        <tabbox id="serial_tabbox" flex="1" class="my_overflow">
             <caption label="Serial Control"/>
             <tabs>
                 <tab label="Items" />
                 <tab label="Units" />
-                <tab label="Summaries" />
+                <tab label="Distributions" />
                 <tab id="serial_manage_subs_tab" label="Subscriptions" />
                 <tab label="Claims" />
             </tabs>
             <tabpanels flex="1">
                 <tabpanel id="serial_manage_items" />
-                <tabpanel id="serial_manage_units" />
-                <tabpanel id="serial_manage_summaries" />
+                <tabpanel id="serial_manage_units"><description>This tab will contain an alternative unit view/editor.</description></tabpanel>
+                <tabpanel id="serial_manage_distributions"><description>This tab will contain a tree of distributions with editors for templates, summaries, and streams.</description></tabpanel>
                 <tabpanel id="serial_manage_subs" />
-                <tabpanel id="serial_manage_claims" />
+                <tabpanel id="serial_manage_claims"><description>This tab will contain a claims interface.</description></tabpanel>
             </tabpanels>
         </tabbox>
 <!--   </groupbox> -->