Skip to content

Commit

Permalink
Adds deposit date into cocina description.
Browse files Browse the repository at this point in the history
closes #2368
  • Loading branch information
justinlittman committed Aug 16, 2022
1 parent dadb3de commit 9e05eab
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 86 deletions.
56 changes: 56 additions & 0 deletions app/services/cocina_generator/description/edtf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

module CocinaGenerator
module Description
# Helper methods for EDTF
class Edtf
def self.props(date)
new(date).props
end

def initialize(date)
@date = date
end

def props
{
encoding: { code: 'edtf' }
}.merge(date.is_a?(EDTF::Interval) ? interval_props : date_props)
end

private

attr_reader :date

def interval_props
{
structuredValue: interval_structured_values
}.tap do |props|
if date.from&.uncertain? || date.to&.uncertain?
props[:qualifier] = 'approximate'
props[:structuredValue].each { |struct_date_val| struct_date_val.delete(:qualifier) }
end
end.compact
end

def interval_structured_values
[].tap do |structured_values|
structured_values << date_props_for(date.from, type: 'start') if date.from
structured_values << date_props_for(date.to, type: 'end') if date.to
end
end

def date_props
date_props_for(date)
end

def date_props_for(props_date, type: nil)
{
qualifier: props_date.uncertain? ? 'approximate' : nil,
value: props_date.edtf.chomp('?'),
type: type
}.compact
end
end
end
end
89 changes: 89 additions & 0 deletions app/services/cocina_generator/description/events_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# frozen_string_literal: true

module CocinaGenerator
module Description
# This generates Events for a work
class EventsGenerator
def self.generate(work_version:)
new(work_version: work_version).generate
end

def initialize(work_version:)
@work_version = work_version
end

def generate
events = deposit_events + Array(created_date_event)
events += publisher_events.presence || Array(published_date_event)
events
end

private

attr_reader :work_version

def publisher_events
@publisher_events ||= ContributorsGenerator.events_from_publisher_contributors(work_version: work_version,
pub_date: published_date_event)
end

def published_date_event
edtf_event_for(date: work_version.published_edtf, event_type: 'publication', date_type: 'publication')
end

def created_date_event
edtf_event_for(date: work_version.created_edtf, event_type: 'creation', date_type: 'creation')
end

def deposit_events
return [] if deposit_versions.blank?

Array(deposit_publication_event) + deposit_modification_events
end

def deposit_publication_event
w3cdtf_event_for(work_version: deposit_publication_version, event_type: 'deposit', date_type: 'publication')
end

def deposit_modification_events
deposit_modification_versions.map do |deposit_version|
w3cdtf_event_for(work_version: deposit_version, event_type: 'deposit', date_type: 'modification')
end
end

def deposit_versions
# Treating this version as a deposit version
@deposit_versions ||= work_version.work.work_versions.filter do |check_work_version|
check_work_version.deposited? || check_work_version == work_version
end
end

def deposit_publication_version
deposit_versions.first
end

def deposit_modification_versions
deposit_versions.slice(1..-1)
end

def edtf_event_for(date:, event_type:, date_type:)
return unless date

Cocina::Models::Event.new(
type: event_type,
date: [Edtf.props(date).merge(type: date_type)]
)
end

def w3cdtf_event_for(work_version:, event_type:, date_type:)
date = work_version.published_at || work_version.updated_at
return unless date

Cocina::Models::Event.new(
type: event_type,
date: [W3cdtf.props(date).merge(type: date_type)]
)
end
end
end
end
76 changes: 6 additions & 70 deletions app/services/cocina_generator/description/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def generate
contributor: ContributorsGenerator.generate(work_version: work_version).presence,
subject: keywords.presence,
note: [abstract, citation].compact.presence,
event: generate_events.presence,
event: EventsGenerator.generate(work_version: work_version).presence,
relatedResource: related_resources.presence,
form: TypesGenerator.generate(work_version: work_version).presence,
access: access,
Expand All @@ -43,15 +43,6 @@ def title
]
end

def generate_events
pub_events = ContributorsGenerator.events_from_publisher_contributors(work_version: work_version,
pub_date: published_date)
return [created_date] + pub_events if pub_events.present? && created_date
return pub_events if pub_events.present? # and no created_date

[created_date, published_date].compact # no pub_events
end

def related_resources
RelatedLinksGenerator.generate(object: work_version) + related_works
end
Expand Down Expand Up @@ -91,57 +82,6 @@ def citation
)
end

def created_date
event_for(work_version.created_edtf, 'creation')
end

def published_date
event_for(work_version.published_edtf, 'publication')
end

def event_for(date, type)
return unless date

date_props = {
encoding: { code: 'edtf' },
type: type
}.merge(date.is_a?(EDTF::Interval) ? interval_props_for(date) : date_props_for(date))

Cocina::Models::Event.new(
type: type,
date: [date_props]
)
end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity

def interval_props_for(date)
structured_values = []
structured_values << date_props_for(date.from, type: 'start') if date.from
structured_values << date_props_for(date.to, type: 'end') if date.to
result_props = {
structuredValue: structured_values
}

if date.from&.uncertain? || date.to&.uncertain?
result_props[:qualifier] = 'approximate'
result_props[:structuredValue].each { |struct_date_val| struct_date_val.delete(:qualifier) }
end

result_props.compact
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity

def date_props_for(date, type: nil)
{
type: type,
qualifier: date.uncertain? ? 'approximate' : nil,
value: date.edtf.chomp('?')
}.compact
end

def access
args = {
accessContact: access_contacts
Expand Down Expand Up @@ -173,18 +113,11 @@ def related_works
end
end

# rubocop:disable Metrics/MethodLength

def admin_metadata
Cocina::Models::DescriptiveAdminMetadata.new(
event: [
Cocina::Models::Event.new(type: 'creation',
date: [
{
value: work_version.work.created_at.strftime('%Y-%m-%d'),
encoding: { code: 'w3cdtf' }
}
])
date: [W3cdtf.props(admin_metadata_creation_date)])
],
note: [
Cocina::Models::DescriptiveValue.new(
Expand All @@ -194,7 +127,10 @@ def admin_metadata
]
)
end
# rubocop:enable Metrics/MethodLength

def admin_metadata_creation_date
work_version.work.work_versions.first&.published_at || work_version.work.created_at
end
end
end
end
15 changes: 15 additions & 0 deletions app/services/cocina_generator/description/w3cdtf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module CocinaGenerator
module Description
# Helper methods for W3CDTF
class W3cdtf
def self.props(date)
{
value: date.strftime('%Y-%m-%d'),
encoding: { code: 'w3cdtf' }
}
end
end
end
end
2 changes: 2 additions & 0 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ CREATE TYPE public.work_access AS ENUM (

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: abstract_contributors; Type: TABLE; Schema: public; Owner: -
--
Expand Down
13 changes: 13 additions & 0 deletions spec/factories/work_versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
access { 'world' }
state { 'first_draft' }
description { 'initial version' }
published_at { Time.zone.parse('2019-01-01') }
work

factory :valid_work_version do
Expand Down Expand Up @@ -159,4 +160,16 @@
license { 'none' }
state { 'reserving_purl' }
end

trait :with_work do
transient do
collection { nil }
owner { association(:user) }
end
work { association :work, collection: collection, owner: owner, work_versions: [instance] }

after(:create) do |work_version, _evaluator|
work_version.work.update(head: work_version)
end
end
end
Loading

0 comments on commit 9e05eab

Please sign in to comment.