houdini/lib/queue_donations.rb
Bradley M. Kuhn 6772312ea7 Relicense all .rb files under new project license.
The primary license of the project is changing to:
  AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later

with some specific files to be licensed under the one of two licenses:
   CC0-1.0
   LGPL-3.0-or-later

This commit is one of the many steps to relicense the entire codebase.

Documentation granting permission for this relicensing (from all past
contributors who hold copyrights) is on file with Software Freedom
Conservancy, Inc.
2018-03-25 15:10:40 -04:00

172 lines
4.8 KiB
Ruby

# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
module QueueDonations
def self.execute_for_donation(id)
donation = Donation.find(id)
return unless donation
execute([donation])
end
def self.execute_all
donations = fetch_donations
return if donations.empty?
donations_ids = donations.collect(&:id)
execute(donations)
end
def self.dry_execute_all
puts "dry push donations to civi"
donations = fetch_donations
return if donations.empty?
donations_ids = donations.collect(&:id)
dry_execute(donations)
end
private
def self.execute(donations)
push(donations)
donations_ids = donations.collect(&:id)
set_queued_for_import_at(donations_ids)
rescue Bunny::Exception, Bunny::ClientTimeout, Bunny::ConnectionTimeout
Rails.logger.warn "Bunny error: QueueDonations.execute failed for ids #{donations_ids}"
return
end
def self.dry_execute(donations)
push(donations)
rescue Bunny::Exception, Bunny::ClientTimeout, Bunny::ConnectionTimeout
Rails.logger.warn "Bunny error: QueueDonations.dry_execute failed for ids #{donations_ids}"
return
end
def self.push(donations)
connection = Bunny.new(
host: Settings.integration.host,
vhost: Settings.integration.vhost,
user: Settings.integration.user,
password: Settings.integration.password
)
connection.start
channel = connection.create_channel
exchange = channel.topic(Settings.integration.exchange, durable: true)
donations.each do |donation|
exchange.publish(
prepare_donation_params(donation).to_json,
routing_key: Settings.integration.routing_key
)
end
connection.close
end
def self.set_queued_for_import_at(ids)
timestamp = Time.current
Qx.update(:donations).
where('id IN ($ids)', ids: ids).
set(queued_for_import_at: timestamp).
execute
end
def self.fetch_donations
Donation.
where('queued_for_import_at IS null').
includes(:supporter, :nonprofit, :tracking, :payment,:recurring_donation)
end
def self.prepare_donation_params(donation)
nonprofit = donation.nonprofit
tracking = donation.tracking
campaign = donation.campaign
recurring = donation.recurring_donation
action_type = :donate
action_technical_type = "cc.wemove.eu:donate"
action_name = "undefined_#{donation.supporter.locale}"
external_id = campaign ? campaign.external_identifier : "cc_default_#{nonprofit.id}"
data = {
action_type: action_type,
action_technical_type: action_technical_type,
create_dt: donation.created_at,
action_name: action_name || "slug-#{campaign.id}-#{donation.supporter.locale}",
external_id: external_id || "cc_#{campaign.id}",
contact: {},
donation: {}
}
data[:contact] = supporter_data(donation.supporter)
data[:donation] = donation_data(donation)
data[:source] = tracking_data(donation.tracking) if donation.tracking
data[:recurring] = recurring_data(donation.recurring_donation) if donation.recurring_donation
data
end
def self.supporter_data(supporter)
{
language: supporter.locale,
firstname: supporter.first_name,
lastname: supporter.last_name,
emails: [
{ email: supporter.email }
],
addresses: [
{ zip: supporter.zip_code, country: supporter.country }],
}
end
def self.donation_data(donation)
common_data = {
amount: donation.amount / 100.0,
currency: donation.nonprofit.currency,
recurring_id: donation.recurring_donation ? "cc_#{donation.recurring_donation.id}" : nil,
external_identifier: "cc_#{donation.id}",
type: donation.recurring ? "recurring" : "single"
}
if donation.card_id
data = common_data.merge({
payment_processor: "stripe",
amount_charged: donation.payment.charge.amount / 100.0,
transaction_id: donation.payment.charge.stripe_charge_id,
status: donation.payment.charge.paid? ? "success" : "not_paid"
})
elsif donation.direct_debit_detail_id
data = common_data.merge({
payment_processor: "sepa",
amount_charged: 0,
transaction_id: "cc_#{donation.id}",
iban: donation.direct_debit_detail.iban,
bic: donation.direct_debit_detail.bic,
account_holder: donation.direct_debit_detail.account_holder_name,
status: "success"
})
end
data
end
def self.recurring_data(recurring)
{
id: recurring.id,
start: recurring.start_date,
time_unit: recurring.time_unit,
active: recurring.active,
}
end
def self.tracking_data(tracking)
{
source: tracking.utm_source,
medium: tracking.utm_medium,
campaign: tracking.utm_campaign,
content: tracking.utm_content
}
end
end