LP1573734_Link_to_sibling_metarecord_bibs_in_record_detail_page
authorblake <blake@mobiusconsortium.org>
Tue, 14 Feb 2017 20:41:34 +0000 (14:41 -0600)
committerKathy Lussier <klussier@masslnc.org>
Thu, 16 Feb 2017 01:51:51 +0000 (20:51 -0500)
This feature will display sibling records when viewing a bib record in the OPAC.
Altered Record.pm to gather up additional metarecord information to pass to
misc_util.tt2 for parsing. Displayed on summary.tt2 styled in responsive in
style.css.tt2. Also fixed the URL in mmr search results for single bib results in
table.tt2. Transcendent bibs needed to be included in the unapi.mmr_mma function.

This code requires the code from LP1629108.
http://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;
h=refs/heads/user/blake/LP1629108-metarecord-constituent-result-reroute

Signed-off-by: blake <blake@mobiusconsortium.org>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>

Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm
Open-ILS/src/sql/Pg/990.schema.unapi.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.LP1573734_Link_to_sibling_metarecord_bibs_in_record_detail_page.sql [new file with mode: 0755]
Open-ILS/src/templates/opac/css/style.css.tt2
Open-ILS/src/templates/opac/parts/misc_util.tt2
Open-ILS/src/templates/opac/parts/record/summary.tt2
Open-ILS/src/templates/opac/parts/result/table.tt2

index 04f3cbe..98aef3c 100644 (file)
@@ -215,6 +215,26 @@ sub load_record {
 
     $self->timelog("past added content stage 2");
 
+    # Gather up metarecord info for display
+    # Let's start by getting the metarecord ID
+    my $mmr_id = OpenILS::Utils::CStoreEditor->new->json_query({
+        select   => { mmrsm => [ 'metarecord' ] },
+        from     => 'mmrsm',
+        where    => { 'source' => $rec_id }
+    })->[0]->{metarecord};
+    # If this record is apart of a meta group, I want to know more
+    if ( $mmr_id ) {
+        my (undef, @metarecord_data) = $self->get_records_and_facets([$mmr_id], undef, {
+            flesh => '{holdings_xml,mra}',
+            metarecord => 1,
+            site => $org_name,
+            depth => $depth,
+            pref_lib => $pref_ou
+        });
+        my ($rec) = grep { $_->{mmr_id} == $mmr_id } @metarecord_data;
+        $ctx->{mmr_id} = $mmr_id;
+        $ctx->{mmr_data} = $rec;
+    }
     return Apache2::Const::OK;
 }
 
index 154c284..b1a407a 100644 (file)
@@ -1366,7 +1366,7 @@ CREATE OR REPLACE FUNCTION unapi.mmr_mra (
                 WITH aou AS (SELECT COALESCE(id, (evergreen.org_top()).id) AS id
                     FROM actor.org_unit WHERE shortname = $5 LIMIT 1)
                 SELECT source
-                FROM metabib.metarecord_source_map, aou
+                FROM metabib.metarecord_source_map mmsm, aou
                 WHERE metarecord = $1 AND (
                     EXISTS (
                         SELECT 1 FROM asset.opac_visible_copies
@@ -1375,6 +1375,7 @@ CREATE OR REPLACE FUNCTION unapi.mmr_mra (
                         LIMIT 1
                     )
                     OR EXISTS (SELECT 1 FROM located_uris(source, aou.id, $10) LIMIT 1)
+                    OR EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = mmsm.source LIMIT 1)
                 )
             )
             SELECT  cmra.aid,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.LP1573734_Link_to_sibling_metarecord_bibs_in_record_detail_page.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.LP1573734_Link_to_sibling_metarecord_bibs_in_record_detail_page.sql
new file mode 100755 (executable)
index 0000000..81b4cd6
--- /dev/null
@@ -0,0 +1,105 @@
+
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION unapi.mmr_mra (
+    obj_id BIGINT,
+    format TEXT,
+    ename TEXT,
+    includes TEXT[],
+    org TEXT,
+    depth INT DEFAULT NULL,
+    slimit HSTORE DEFAULT NULL,
+    soffset HSTORE DEFAULT NULL,
+    include_xmlns BOOL DEFAULT TRUE,
+    pref_lib INT DEFAULT NULL
+) RETURNS XML AS $F$
+    SELECT  XMLELEMENT(
+        name attributes,
+        XMLATTRIBUTES(
+            CASE WHEN $9 THEN 'http://open-ils.org/spec/indexing/v1' ELSE NULL END AS xmlns,
+            'tag:open-ils.org:U2@mmr/' || $1 AS metarecord
+        ),
+        (SELECT XMLAGG(foo.y)
+          FROM (
+            WITH sourcelist AS (
+                WITH aou AS (SELECT COALESCE(id, (evergreen.org_top()).id) AS id
+                    FROM actor.org_unit WHERE shortname = $5 LIMIT 1)
+                SELECT source
+                FROM metabib.metarecord_source_map mmsm, aou
+                WHERE metarecord = $1 AND (
+                    EXISTS (
+                        SELECT 1 FROM asset.opac_visible_copies
+                        WHERE record = source AND circ_lib IN (
+                            SELECT id FROM actor.org_unit_descendants(aou.id, $6))
+                        LIMIT 1
+                    )
+                    OR EXISTS (SELECT 1 FROM located_uris(source, aou.id, $10) LIMIT 1)
+                    OR EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source src ON (b.source = src.id) WHERE src.transcendant AND b.id = mmsm.source LIMIT 1)
+                )
+            )
+            SELECT  cmra.aid,
+                    XMLELEMENT(
+                        name field,
+                        XMLATTRIBUTES(
+                            cmra.attr AS name,
+                            cmra.value AS "coded-value",
+                            cmra.aid AS "cvmid",
+                            rad.composite,
+                            rad.multi,
+                            rad.filter,
+                            rad.sorter,
+                            cmra.source_list
+                        ),
+                        cmra.value
+                    )
+              FROM  (
+                SELECT DISTINCT aid, attr, value, STRING_AGG(x.id::TEXT, ',') AS source_list
+                  FROM (
+                    SELECT  v.source AS id,
+                            c.id AS aid,
+                            c.ctype AS attr,
+                            c.code AS value
+                      FROM  metabib.record_attr_vector_list v
+                            JOIN config.coded_value_map c ON ( c.id = ANY( v.vlist ) )
+                    ) AS x
+                    JOIN sourcelist ON (x.id = sourcelist.source)
+                    GROUP BY 1, 2, 3
+                ) AS cmra
+                JOIN config.record_attr_definition rad ON (cmra.attr = rad.name)
+                UNION ALL
+            SELECT  umra.aid,
+                    XMLELEMENT(
+                        name field,
+                        XMLATTRIBUTES(
+                            umra.attr AS name,
+                            rad.composite,
+                            rad.multi,
+                            rad.filter,
+                            rad.sorter
+                        ),
+                        umra.value
+                    )
+              FROM  (
+                SELECT DISTINCT aid, attr, value
+                  FROM (
+                    SELECT  v.source AS id,
+                            m.id AS aid,
+                            m.attr AS attr,
+                            m.value AS value
+                      FROM  metabib.record_attr_vector_list v
+                            JOIN metabib.uncontrolled_record_attr_value m ON ( m.id = ANY( v.vlist ) )
+                    ) AS x
+                    JOIN sourcelist ON (x.id = sourcelist.source)
+                ) AS umra
+                JOIN config.record_attr_definition rad ON (umra.attr = rad.name)
+                ORDER BY 1
+
+            )foo(id,y)
+        )
+    )
+$F$ LANGUAGE SQL STABLE;
+  
+COMMIT;
+
index 413c3c9..e9fccea 100644 (file)
@@ -485,6 +485,33 @@ div.format_icon {
     margin-right: 17px;
 }
 
+#metarecord_population {
+    overflow: hidden;
+    width: 40%;
+    padding-bottom: 10px;
+}
+
+.metarecord_population_span_link {
+    line-height: 20px;
+}
+
+.metarecord_population_format {
+    border-right: thin;
+    display: inline-block;
+    margin-right: 1em;
+    padding-right: 1em;
+    vertical-align: top;
+}
+
+.metarecord_population_item_lang {
+    display: inline-block;
+    vertical-align: top;
+}
+
+.metarecord_population_all {
+    padding-top:10px;
+}
+
 .result_util {
     border-bottom: 1px dotted [% css_colors.accent_light %];
     padding-top: 6px;
@@ -2002,6 +2029,15 @@ a.preflib_change {
     h2.rdetail_uris {
         clear: both;
     }
+    #metarecord_population {
+        overflow: hidden;
+        width: 100%;
+    }
+    .metarecord_population_span_link {
+    }
+    .metarecord_population_item_lang {
+        float: none;
+    }
     .search_catalog_lbl {
        margin-left: 0;
        white-space: nowrap;
index a01ac50..d7ab819 100644 (file)
             END;
         END;
 
+        mmr_unique_bib = [];
         # "mattype" == "custom marc format specifier"
         icon_style = ctx.get_cgf('opac.icon_attr').value || 'item_type';
         formats_xpath = '//*[local-name()="attributes"]/*[local-name()="field"][@name="' _ icon_style _ '"]';
                     format.itemtype = schema_typemap.$type || 'CreativeWork';
                     format.search_format = ccvm.code;
                     format.source_bibs = this_icon_source.split(',');
-
+                    FOR bib_source IN format.source_bibs;
+                        IF NOT mmr_unique_bib.grep(bib_source).size; mmr_unique_bib.push(bib_source); END;
+                    END;
                     args.all_formats.push(format); # metarecords want all formats
 
                     IF !args.format_label;
                 END;
             END;
         END;
-       
+
+        formats_xpath = '//*[local-name()="attributes"]/*[local-name()="field"][@name="item_lang"]';
+        args.all_lang = [];
+        FOR node IN xml.findnodes(formats_xpath);
+            IF node AND node.textContent;
+                ccvm = ctx.get_ccvm(node.getAttribute('cvmid'));
+                NEXT IF ccvm.opac_visible == 'f';
+
+                lang = {};
+                this_source = node.getAttribute('source_list');
+                including = 'F';
+                # Just display everything if we don't have the data
+                IF NOT args.mr_constituent_ids OR NOT this_source;
+                    including = 'T';
+                # We have an array of search-included bib IDs and we have the bib ID that this lang belongs to
+                ELSE;
+                    FOR mr_constituent_id IN args.mr_constituent_ids;
+                        IF this_source.split(',').grep('^' _ mr_constituent_id _ '$' ).size;
+                            # This bib appears to be in the array of filtered bibs
+                            including = 'T';
+                        END;
+                    END;
+                END;
+                IF including == 'T';
+                    lang.label = ccvm.search_label || ccvm.value;
+                    lang.itemtype = schema_typemap.$type || 'CreativeWork';
+                    lang.search_format = node.textContent;
+                    lang.source_bibs = this_source.split(',');
+                    FOR bib_source IN lang.source_bibs;
+                        IF NOT mmr_unique_bib.grep(bib_source).size; mmr_unique_bib.push(bib_source); END;
+                    END;
+
+                    args.all_lang.push(lang); # metarecords want all
+                END;
+            END;
+        END;
+        args.mmr_unique_bib = mmr_unique_bib;
+
         args.bibid = [];
         FOR bibid IN xml.findnodes('//*[@tag="901"]/*[@code="c"]');
             args.bibid.push(bibid.textContent);
index 1068e72..d80958d 100644 (file)
@@ -166,11 +166,12 @@ IF num_uris > 0;
     [%- IF num_uris > 1 %]</ul>[% END %]
 </div>
 [%- END %]
-[%- # Hold/copy summary
-    IF ctx.copy_summary.0.count
-%]
 <div id="copy_hold_counts">
-[%- INCLUDE "opac/parts/record/copy_counts.tt2" %]
+[%-
+# Hold/copy summary
+IF ctx.copy_summary.0.count;
+INCLUDE "opac/parts/record/copy_counts.tt2";
+%]
     <span id="rdetail_hold_counts">
         <h2>[% l('Current holds') %]</h2>
         <p>
@@ -190,9 +191,66 @@ IF num_uris > 0;
             %]
         </p>
     </span>
-[%- INCLUDE "opac/parts/record/copy_table.tt2" copies=ctx.copies %]
-</div>
 [%- END %]
+<div id="metarecord_population">
+[%-
+# l( 'mmr id = ' _ ctx.mmr_id );
+# l( 'mmr data = ' _ ctx.mmr_data );
+mmr_attrs = {marc_xml => ctx.mmr_data.marc_xml};
+PROCESS get_marc_attrs args=mmr_attrs;
+
+IF args.mmr_unique_bib.size > 1;
+%]
+<h3>View Other Formats and Editions</h3>
+<span class="metarecord_population_format">
+[%- IF mmr_attrs.format_label;
+    FOR format IN mmr_attrs.all_formats;
+
+        link = mkurl(ctx.opac_root _ '/record/' _ format.source_bibs.0);
+        IF format.source_bibs.size > 1;
+            link = mkurl( ctx.opac_root _ '/results', { modifier => 'metabib', metarecord => ctx.mmr_id, 'fi:icon_format' => format.search_format, 'fi:from_metarecord' => ctx.mmr_id }, stop_parms.merge(expert_search_parms, general_search_parms, browse_search_parms, facet_search_parms, ['qtype','fi:search_format','fi:icon_format','fi:item_lang','fi:from_metarecord']) );
+        END; -%]
+        <span class="metarecord_population_span_link">
+            <a href="[%- l( link ) %]">
+        [% format.label | html %]
+        ([%- l( format.source_bibs.size ) %])
+        </a></span><br />
+
+    [%- END %]
+    </span>
+    [%- IF mmr_attrs.all_lang.size > 0 %]
+    <span class="metarecord_population_item_lang">
+    [% FOR lang IN mmr_attrs.all_lang;
+        link = mkurl(ctx.opac_root _ '/record/' _ lang.source_bibs.0);
+        IF lang.source_bibs.size > 1;
+            USE url(ctx.opac_root _ '/results');
+            link = mkurl( ctx.opac_root _ '/results', { modifier => 'metabib', metarecord => ctx.mmr_id, 'fi:item_lang' => lang.search_format, 'fi:from_metarecord' => ctx.mmr_id }, stop_parms.merge(expert_search_parms, general_search_parms, browse_search_parms, facet_search_parms, ['qtype','fi:search_format','fi:icon_format','fi:item_lang','fi:from_metarecord']) );
+        END; -%]
+        <span class="metarecord_population_span_link">
+            <a href="[%- l( link ) %]">
+        [% lang.label | html %]
+        ([%- l( lang.source_bibs.size ) %])
+        </a></span><br />
+    [%- END %]
+    </span> <!-- metarecord_population_item_lang -->
+[%- END %]
+<div class="metarecord_population_all">
+    [%
+    link = mkurl( ctx.opac_root _ '/results', { modifier => 'metabib', metarecord => ctx.mmr_id, 'fi:from_metarecord' => ctx.mmr_id }, stop_parms.merge(expert_search_parms, general_search_parms, browse_search_parms, facet_search_parms, ['qtype','fi:search_format','fi:icon_format','fi:item_lang','fi:from_metarecord'] ) );
+    %]
+    <span class="metarecord_population_span_link">
+        <a href="[%- l( link ) %]">View all [%- args.mmr_unique_bib.size %] formats and editions
+        </a></span><br />
+</div>
+[%- END;
+END # ending tag for IF args.mmr_unique_bib.size > 1; %]
+</div> <!-- metarecord_population -->
+[%-
+IF ctx.copy_summary.0.count;
+INCLUDE "opac/parts/record/copy_table.tt2" copies=ctx.copies;
+END;
+ %]
+</div>
 
 <h2 id='rdetail_record_details'>[% l("Record details") %]</h2>
 <ul>
index 8f59022..5f3cbc3 100644 (file)
@@ -86,7 +86,7 @@
                                 ELSE;
                                     # for MR, bre_id refers to the master and in
                                     # this case, only, record
-                                    record_url = mkurl(ctx.opac_root _ '/record/' _ rec.bre_id, { badges => rec.badges.join(',') });
+                                    record_url = mkurl(ctx.opac_root _ '/record/' _ attrs.mr_constituent_ids.0, { badges => rec.badges.join(',') });
                                 END;
                                 hold_type = 'M';
                             ELSE;