diff --git a/lib/constants.rb b/lib/constants.rb index 94cede7ed..f15ecb337 100644 --- a/lib/constants.rb +++ b/lib/constants.rb @@ -226,4 +226,34 @@ module Constants 852 853 863 866 867 868 901 910 918 923 924 930 935 940 948 949 950 955 960 962 980 981 983 990 993 998 ] + + INSTANCE_TYPE_LEADER_CODE = { + 'cartographic dataset' => 'e', + 'cartographic image' => 'e', + 'cartographic moving image' => 'e', + 'cartographic tactile image' => 'e', + 'cartographic tactile three-dimensional form' => 'e', + 'cartographic three-dimensional form' => 'e', + 'computer dataset' => 'm', + 'computer program' => 'm', + 'notated music' => 'c', + 'performed music' => 'j', + 'sounds' => 'i', + 'spoken word' => 'i', + 'still image' => 'k', + 'tactile image' => 'k', + 'tactile notated music' => 'c', + 'tactile three-dimensional form' => 'r', + 'text' => 'a', + 'three-dimensional form' => 'r', + 'three-dimensional moving image' => 'r', + 'two-dimensional moving image' => 'g' + } + + MODE_OF_ISSUANCE_LEADER_CODE = { + 'integrating resource' => 'i', + 'multipart monograph' => 'a', + 'serial' => 's', + 'single unit' => 'm' + } end diff --git a/lib/folio/marc_record_instance_mapper.rb b/lib/folio/marc_record_instance_mapper.rb index 2003b8ad2..b98e63a3f 100644 --- a/lib/folio/marc_record_instance_mapper.rb +++ b/lib/folio/marc_record_instance_mapper.rb @@ -3,9 +3,13 @@ module Folio # Creates a Marc Record for an Folio instance class MarcRecordInstanceMapper - # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength + # rubocop:disable Metrics/AbcSize, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/MethodLength def self.build(instance, holdings) MARC::Record.new.tap do |marc| + # Add what we can to the leader from FOLIO data + marc.leader[6] = Constants::INSTANCE_TYPE_LEADER_CODE[instance.dig('instanceType', 'name')] || ' ' + marc.leader[7] = Constants::MODE_OF_ISSUANCE_LEADER_CODE[instance.dig('modeOfIssuance', 'name')] || ' ' + marc.append(MARC::ControlField.new('001', instance['hrid'])) # mode of issuance # identifiers @@ -129,7 +133,7 @@ def self.build(instance, holdings) # date updated end.to_hash end - # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength + # rubocop:enable Metrics/AbcSize, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/MethodLength # The FOLIO data can either be a plain string (pre-Poppy) or a hash (post-Poppy) def self.folio_value(folio_data) diff --git a/lib/traject/readers/folio_postgres_reader.rb b/lib/traject/readers/folio_postgres_reader.rb index 50b6c6ebe..592e46898 100644 --- a/lib/traject/readers/folio_postgres_reader.rb +++ b/lib/traject/readers/folio_postgres_reader.rb @@ -306,8 +306,9 @@ def contents_sql_query(conditions, addl_from: nil) '[]'::jsonb END, 'administrativeNotes', '[]'::jsonb, - 'notes', COALESCE((SELECT jsonb_agg(e) FROM jsonb_array_elements(vi.jsonb -> 'notes') AS e WHERE NOT COALESCE((e ->> 'staffOnly')::bool, false)), '[]'::jsonb) - + 'notes', COALESCE((SELECT jsonb_agg(e) FROM jsonb_array_elements(vi.jsonb -> 'notes') AS e WHERE NOT COALESCE((e ->> 'staffOnly')::bool, false)), '[]'::jsonb), + 'instanceType', COALESCE(jsonb_agg(jsonb_build_object('name', it.jsonb ->> 'name')) -> 0, '{}'::jsonb), + 'modeOfIssuance', COALESCE(jsonb_agg(jsonb_build_object('name', moi.jsonb ->> 'name')) -> 0, '{}'::jsonb) ), 'source_record', COALESCE(jsonb_agg(DISTINCT mr."content"), '[]'::jsonb), 'items', @@ -429,6 +430,12 @@ def contents_sql_query(conditions, addl_from: nil) -- Holdings Ill policy relation LEFT JOIN sul_mod_inventory_storage.ill_policy ilp ON hr.illpolicyid = ilp.id + -- Instance Type (Resource type) relation + LEFT JOIN sul_mod_inventory_storage.instance_type it + ON vi.instancetypeid = it.id + -- Mode of Issuance relation + LEFT JOIN sul_mod_inventory_storage.mode_of_issuance moi + ON vi.modeofissuanceid = moi.id LEFT JOIN sul_mod_source_record_storage.records_lb rs ON rs.external_id = vi.id AND rs.state = 'ACTUAL' LEFT JOIN sul_mod_source_record_storage.marc_records_lb mr diff --git a/spec/lib/folio/marc_record_instance_mapper_spec.rb b/spec/lib/folio/marc_record_instance_mapper_spec.rb new file mode 100644 index 000000000..7bd4fa14c --- /dev/null +++ b/spec/lib/folio/marc_record_instance_mapper_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Folio::MarcRecordInstanceMapper do + describe '.build' do + let(:instance) do + { + 'id' => '8d3623d4-60ab-4aa6-8637-1c0bf6cfb297', + 'hrid' => 'in00000003052', + 'notes' => [], + 'title' => "Akira Kurosawa's dreams", + 'series' => [], + 'source' => 'FOLIO', + 'editions' => [], + 'subjects' => [], + 'languages' => [], + 'identifiers' => [], + 'publication' => [], + 'contributors' => [], + 'electronicAccess' => [], + 'publicationRange' => [], + 'physicalDescriptions' => [], + 'publicationFrequency' => [] + } + end + + let(:holdings) { [{ 'electronicAccess' => [] }] } + + context 'when instance type is not available' do + it 'leaves leader byte 6 unset' do + marc = described_class.build(instance, holdings) + expect(marc['leader'][6]).to eq(' ') + end + end + + context 'when instance type is available' do + let(:instance_with_instance_type) do + instance.merge( + 'instanceType' => { + 'name' => 'two-dimensional moving image' + } + ) + end + it 'sets leader byte 6' do + marc = described_class.build(instance_with_instance_type, holdings) + expect(marc['leader'][6]).to eq('g') + end + end + + context 'when mode of issuance is not available' do + it 'leaves leader byte 7 unset' do + marc = described_class.build(instance, holdings) + expect(marc['leader'][7]).to eq(' ') + end + end + + context 'when mode of issuance is available' do + let(:instance_with_mode_of_issuance) do + instance.merge( + 'modeOfIssuance' => { + 'name' => 'single unit' + } + ) + end + it 'sets leader byte 7' do + marc = described_class.build(instance_with_mode_of_issuance, holdings) + expect(marc['leader'][7]).to eq('m') + end + end + end +end