Module: Export::CSV::Dwc::Extension::Checklist::TypesAndSpecimen

Defined in:
lib/export/csv/dwc/extension/checklist/types_and_specimen.rb

Overview

CSV for Types and Specimen extension (for checklist archives). See http://rs.gbif.org/extension/gbif/1.0/typesandspecimen.xml

Note: Currently only includes fields that can be populated from DwcOccurrence. Type-specific fields like typeDesignationType and typeDesignatedBy would require accessing TypeMaterial objects directly.

Constant Summary collapse

GBIF =
Export::Dwca::GbifProfile::TypeSpecimen
CHECKLIST_FIELDS =

Fields used in checklist exports (subset of full GBIF profile). Only including fields that can be populated from DwcOccurrence data from CollectionObject records with type materials.

[
  :id, # Required for DwC-A star joins (taxonID, an OTU UUID)
  :typeStatus,
  :scientificName,
  :taxonRank,
  :occurrenceID,
  :institutionCode,
  :collectionCode,
  :catalogNumber,
  :locality,
  :sex,
  :recordedBy,
  :verbatimEventDate
].freeze
HEADERS =
CHECKLIST_FIELDS
HEADERS_NAMESPACES =
CHECKLIST_FIELDS.map do |field|
  field == :id ? '' : GBIF::NAMESPACES[field]
end.freeze

Class Method Summary collapse

Class Method Details

.csv(scope, taxon_name_id_to_taxon_id, accepted_name_mode:) ⇒ String

Generate CSV for types and specimen extension using only DwcOccurrence data.

Parameters:

  • scope (ActiveRecord::Relation)

    DwcOccurrence records

  • taxon_name_id_to_taxon_id (Hash)

    taxon_name_id => OTU UUID (used as dwc:taxonID in the checklist core)

  • accepted_name_mode (String)

    checklist synonym handling mode

Returns:

  • (String)

    CSV content



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/export/csv/dwc/extension/checklist/types_and_specimen.rb', line 40

def self.csv(scope, taxon_name_id_to_taxon_id, accepted_name_mode:)
  tbl = []
  tbl[0] = HEADERS

  co_scope = scope
    .where(dwc_occurrence_object_type: 'CollectionObject')
    .where.not(typeStatus: [nil, ''])

  otu_to_taxon_name_id = co_scope
    .joins('JOIN otus ON otus.id = dwc_occurrences.otu_id')
    .joins('JOIN taxon_names ON taxon_names.id = otus.taxon_name_id')
    .pluck(
      Arel.sql('dwc_occurrences.otu_id'),
      Arel.sql(
        if accepted_name_mode == ::Export::Dwca::Checklist::Data::ACCEPTED_NAME_USAGE_ID
          'taxon_names.id'
        else
          'COALESCE(taxon_names.cached_valid_taxon_name_id, taxon_names.id)'
        end
      )
    )
    .to_h

  co_scope.find_each do |dwc_occ|
    taxon_name_id = otu_to_taxon_name_id[dwc_occ.otu_id]
    next unless taxon_name_id

    taxon_id = taxon_name_id_to_taxon_id[taxon_name_id]
    next unless taxon_id

    type_status_str = dwc_occ.typeStatus

    type_statuses = type_status_str
      .split(Export::Dwca::DELIMITER)
      .map(&:strip)
      .reject(&:blank?)
      .uniq

    type_statuses.each do |type_status|
      row = [
        taxon_id,
        type_status,
        dwc_occ.scientificName,
        dwc_occ.taxonRank,
        dwc_occ.occurrenceID,
        dwc_occ.institutionCode,
        dwc_occ.collectionCode,
        dwc_occ.catalogNumber,
        dwc_occ.locality,
        dwc_occ.sex,
        dwc_occ.recordedBy,
        dwc_occ.verbatimEventDate
      ]

      tbl << row
    end
  end

  ::Export::Dwca.output_csv(tbl)
end