Skip to content

Commit

Permalink
Merge pull request #45 from CDL-Dryad/shopping-cart-report
Browse files Browse the repository at this point in the history
 Shopping cart report
  • Loading branch information
sfisher authored Jan 14, 2020
2 parents f1a01ab + c159e2b commit b7fb0a1
Show file tree
Hide file tree
Showing 16 changed files with 222 additions and 42 deletions.
2 changes: 1 addition & 1 deletion spec/factories/stash_engine/curation_activities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
# https://stackoverflow.com/questions/8751175/skip-callbacks-on-factory-girl-and-rspec
ca.define_singleton_method(:submit_to_datacite) {}
ca.define_singleton_method(:update_solr) {}
ca.define_singleton_method(:submit_to_stripe) {}
ca.define_singleton_method(:process_payment) {}
ca.define_singleton_method(:email_status_change_notices) {}
ca.define_singleton_method(:email_orcid_invitations) {}
end
Expand Down
2 changes: 1 addition & 1 deletion spec/mocks/curation_activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def neuter_curation_callbacks!
# callback explicitly.
allow_any_instance_of(StashEngine::CurationActivity).to receive(:submit_to_datacite).and_return(true)
allow_any_instance_of(StashEngine::CurationActivity).to receive(:update_solr).and_return(true)
allow_any_instance_of(StashEngine::CurationActivity).to receive(:submit_to_stripe).and_return(true)
allow_any_instance_of(StashEngine::CurationActivity).to receive(:process_payment).and_return(true)
allow_any_instance_of(StashEngine::CurationActivity).to receive(:email_status_change_notices).and_return(true)
allow_any_instance_of(StashEngine::CurationActivity).to receive(:email_orcid_invitations).and_return(true)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def lock_down_admin_only_params
# all this bogus return false stuff is to prevent double render errors in some circumstances
return if check_superuser_restricted_params == false
return if check_may_set_user_id == false
return if check_may_set_invoice_id == false
return if check_may_set_payment_id == false
end

def check_superuser_restricted_params
Expand Down Expand Up @@ -211,10 +211,10 @@ def check_may_set_user_id
false
end

def check_may_set_invoice_id
return if params['invoiceId'].nil?
def check_may_set_payment_id
return if params['paymentId'].nil?
unless @user.role == 'superuser'
render json: { error: 'Unauthorized: only superuser roles may set an invoiceId' }.to_json, status: 401
render json: { error: 'Unauthorized: only superuser roles may set a paymentId' }.to_json, status: 401
return false
end
false
Expand Down
3 changes: 2 additions & 1 deletion stash/stash_api/app/models/stash_api/dataset_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def parse
@hash[:authors]&.each { |author| add_author(json_author: author) }
StashDatacite::Description.create(description: @hash[:abstract], description_type: 'abstract', resource_id: @resource.id)
TO_PARSE.each { |item| dynamic_parse(my_class: item) }
@resource.identifier.invoice_id = @hash['invoiceId']
@resource.identifier.payment_type = @hash['paymentType']
@resource.identifier.payment_id = @hash['paymentId']
@resource.identifier.save
@resource.identifier
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ module StashApi
'abstract' =>
'Cyberneticists agree that concurrent models are an interesting new topic in the field of machine learning.',
'userId' => @user2.id,
'invoiceId' => 'invoice-123'
'paymentId' => 'invoice-123',
'paymentType' => 'stripe'
}.with_indifferent_access

@update_metadata = {
Expand Down Expand Up @@ -135,8 +136,9 @@ module StashApi
expect(resource.current_editor_id).to eq(@user2.id)
end

it 'puts the invoiceId on the identifier' do
expect(@stash_identifier.invoice_id). to eq('invoice-123')
it 'puts the paymentId on the identifier' do
expect(@stash_identifier.payment_id). to eq('invoice-123')
expect(@stash_identifier.payment_type). to eq('stripe')
end
end

Expand Down
18 changes: 13 additions & 5 deletions stash/stash_engine/app/models/stash_engine/curation_activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CurationActivity < ActiveRecord::Base # rubocop:disable Metrics/ClassLengt
# ------------------------------------------

# When the status is published/embargoed send to Stripe and DataCite
after_create :submit_to_datacite, :update_solr, :submit_to_stripe, :remove_peer_review,
after_create :submit_to_datacite, :update_solr, :process_payment, :remove_peer_review,
if: proc { |ca|
!ca.resource.skip_datacite_update && (ca.published? || ca.embargoed?) &&
latest_curation_status_changed?
Expand Down Expand Up @@ -118,10 +118,18 @@ def latest_curation_status_changed?

# Callbacks
# ------------------------------------------
def submit_to_stripe
return unless ready_for_payment? &&
resource.identifier&.user_must_pay?
def process_payment
return unless ready_for_payment?

if resource.identifier&.user_must_pay?
submit_to_stripe
else
resource.identifier&.record_payment
end
end

def submit_to_stripe
return unless ready_for_payment?
inv = Stash::Payments::Invoicer.new(resource: resource, curator: user)
inv.charge_user_via_invoice
end
Expand Down Expand Up @@ -242,7 +250,7 @@ def update_publication_flags
def ready_for_payment?
resource&.identifier&.reload
StashEngine.app&.payments&.service == 'stripe' &&
resource&.identifier&.invoice_id.nil? &&
resource&.identifier&.payment_id.nil? &&
(status == 'published' || status == 'embargoed')
end

Expand Down
37 changes: 37 additions & 0 deletions stash/stash_engine/app/models/stash_engine/identifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,23 @@ def user_must_pay?
(!submitter_affiliation.present? || !submitter_affiliation.fee_waivered?)
end

def record_payment
return if payment_type.present?
if submitter_affiliation&.fee_waivered?
self.payment_type = 'waiver'
self.payment_id = submitter_affiliation.country_name
elsif institution_will_pay?
self.payment_type = 'institution'
self.payment_id = latest_resource&.tenant&.tenant_id
elsif journal_will_pay?
self.payment_type = 'journal-' + publication_data('paymentPlanType')
self.payment_id = publication_issn
else
self.payment_type = 'unknown'
end
save
end

def publication_data(field_name)
return nil if publication_issn.nil?
url = APP_CONFIG.old_dryad_url + '/api/v1/journals/' + publication_issn
Expand Down Expand Up @@ -264,6 +281,10 @@ def journal_customer_id
publication_data('stripeCustomerID')
end

def journal_sponsor_name
publication_data('sponsorName')
end

def journal_notify_contacts
publication_data('notifyContacts')
end
Expand Down Expand Up @@ -318,6 +339,22 @@ def embargoed_until_article_appears?
found_article_appears
end

# returns the date on which this identifier was approved for publication
# (i.e., the date on which it entered the status 'published' or 'embargoed'
def approval_date
return nil unless %w[published embargoed].include?(pub_state)

found_approval_date = nil
resources.each do |res|
res.curation_activities.each do |ca|
next unless %w[published embargoed].include?(ca.status)
found_approval_date = ca.created_at
break
end
end
found_approval_date
end

# returns the publication state based on history
# finds the latest applicable state from terminal states for each resource/version.
# We only really care about whether it's some form of published, embargoed or withdrawn
Expand Down
32 changes: 32 additions & 0 deletions stash/stash_engine/db/migrate/20200111013011_add_payment_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class AddPaymentType < ActiveRecord::Migration
def up
rename_column :stash_engine_identifiers, :invoice_id, :payment_id
add_column :stash_engine_identifiers, :payment_type, :string, after: :search_words
StashEngine::Identifier.reset_column_information
StashEngine::Identifier.all.each do |i|
if i.payment_id
if i.payment_id.start_with?('in_')
i.update_column(:payment_type, 'stripe')
else
# else, separate on the colon, set payment_type to part before colon, and payment_id to rest
found_type, found_id = i.payment_id.match(/(.+):(.+)/).captures
next unless found_type && found_id
i.update_column(:payment_id, found_id)
i.update_column(:payment_type, found_type)
end
end
end
end

def down
StashEngine::Identifier.all.each do |i|
next unless i.payment_id
if i.payment_type != 'stripe'
new_id = "#{i.payment_type}:#{i.payment_id}"
i.update_column(:payment_id, new_id)
end
end
rename_column :stash_engine_identifiers, :payment_id, :invoice_id
remove_column :stash_engine_identifiers, :payment_type
end
end
10 changes: 6 additions & 4 deletions stash/stash_engine/lib/stash/payments/invoicer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ def charge_user_via_invoice
return unless customer_id.present?
create_invoice_items_for_dpc(customer_id)
invoice = create_invoice(customer_id)
resource.identifier.invoice_id = invoice.id
resource.identifier.payment_id = invoice.id
resource.identifier.payment_type = 'stripe'
resource.identifier.save
invoice.send_invoice
end
Expand All @@ -40,15 +41,16 @@ def charge_journal_via_invoice
return unless customer_id.present?
# the following line was creating invoice_item from return value, but didn't seem used anywhere
create_invoice_items_for_dpc(customer_id)
resource.identifier.invoice_id = invoice_item&.id
resource.identifier.payment_id = "#{resource.identifier&.publication_issn}-#{invoice_item&.id}"
resource.identifier.payment_type = 'journal'
resource.identifier.save
end

def external_service_online?
set_api_key
latest = StashEngine::Identifier.where.not(invoice_id: nil).order(updated_at: :desc).first
latest = StashEngine::Identifier.where.not(payment_id: nil).order(updated_at: :desc).first
return false unless latest.present?
Stripe::Charge.retrieve(latest.invoice_id).present?
Stripe::Charge.retrieve(latest.payment_id).present?
end

# takes a size and returns overage charges in cents
Expand Down
33 changes: 33 additions & 0 deletions stash/stash_engine/lib/tasks/stash_engine_tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,39 @@ namespace :identifiers do
end
end

desc 'Generate a report of items that have been published in a given month'
task shopping_cart_report: :environment do
# Get the year-month specified in YEAR_MONTH environment variable.
# If none, default to the previously completed month.
if ENV['YEAR_MONTH'].blank?
p 'No month specified, assuming last month.'
year_month = 1.month.ago.strftime('%Y-%m')
else
year_month = ENV['YEAR_MONTH']
end
p "Writing Shopping Cart Report for #{year_month} to file..."
CSV.open("shopping_cart_report_#{year_month}.csv", 'w') do |csv|
csv << ['DOI', 'Approval Date', 'Payment Type', 'Payment ID', 'Journal Name', 'Sponsor Name']
StashEngine::Identifier.publicly_viewable.each do |i|
approval_date_str = i.approval_date&.strftime('%Y-%m-%d')
if approval_date_str&.start_with?(year_month)
csv << [i.identifier, approval_date_str, i.payment_type, i.payment_id, i.publication_name, i.journal_sponsor_name]
end
end
end
# Exit cleanly (don't let rake assume that an extra argument is another task to process)
exit
end

desc 'populate payment info'
task load_payment_info: :environment do
p 'Populating payment information for published/embargoed items'
StashEngine::Identifier.publicly_viewable.where(payment_type: nil).each do |i|
i.record_payment
p "#{i.id} #{i.identifier} #{i.payment_type} #{i.payment_id}"
end
end

desc 'populate publicationName'
task load_publication_names: :environment do
p "Searching CrossRef and the Journal API for publication names: #{Time.now.utc}"
Expand Down
12 changes: 10 additions & 2 deletions stash/stash_engine/spec/db/stash_engine/curation_activity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ module StashEngine
allow_any_instance_of(Stash::Doi::IdGen).to receive(:update_identifier_metadata).and_return(true)
allow_any_instance_of(Stash::Payments::Invoicer).to receive(:new).and_return(true)
allow_any_instance_of(Stash::Payments::Invoicer).to receive(:charge_user_via_invoice).and_return(true)
# allow_any_instance_of(StashEngine::CurationActivity).to receive(:update_publication_flags).and_return(true)
end

context :update_solr do
Expand Down Expand Up @@ -129,7 +128,7 @@ module StashEngine

end

context :submit_to_stripe do
context :process_payment do

before(:each) do
allow_any_instance_of(StashEngine::CurationActivity).to receive(:email_status_change_notices).and_return(true)
Expand Down Expand Up @@ -164,6 +163,15 @@ module StashEngine
ca.save
end

it 'does not call submit_to_stripe when user is not responsible for payment' do
allow_any_instance_of(StashEngine::CurationActivity).to receive(:ready_for_payment?).and_return(true)
allow_any_instance_of(StashEngine::Identifier).to receive(:user_must_pay?).and_return(false)
ca = CurationActivity.new(resource_id: @resource.id, status: 'embargoed')
expect(ca).to receive(:process_payment)
expect(ca).not_to receive(:submit_to_stripe)
ca.save
end

end

context :email_status_change_notices do
Expand Down
Loading

0 comments on commit b7fb0a1

Please sign in to comment.