2019-07-30 21:29:24 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-25 16:15:39 +00:00
|
|
|
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
2018-03-25 17:30:42 +00:00
|
|
|
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?
|
2019-07-30 21:29:24 +00:00
|
|
|
|
2018-03-25 17:30:42 +00:00
|
|
|
donations_ids = donations.collect(&:id)
|
|
|
|
|
|
|
|
execute(donations)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.dry_execute_all
|
2019-07-30 21:29:24 +00:00
|
|
|
puts 'dry push donations to civi'
|
2018-03-25 17:30:42 +00:00
|
|
|
donations = fetch_donations
|
|
|
|
return if donations.empty?
|
2019-07-30 21:29:24 +00:00
|
|
|
|
2018-03-25 17:30:42 +00:00
|
|
|
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}"
|
2019-07-30 21:29:24 +00:00
|
|
|
nil
|
2018-03-25 17:30:42 +00:00
|
|
|
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}"
|
2019-07-30 21:29:24 +00:00
|
|
|
nil
|
2018-03-25 17:30:42 +00:00
|
|
|
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
|
2019-07-30 21:29:24 +00:00
|
|
|
Qx.update(:donations)
|
|
|
|
.where('id IN ($ids)', ids: ids)
|
|
|
|
.set(queued_for_import_at: timestamp)
|
|
|
|
.execute
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.fetch_donations
|
2019-07-30 21:29:24 +00:00
|
|
|
Donation
|
|
|
|
.where('queued_for_import_at IS null')
|
|
|
|
.includes(:supporter, :nonprofit, :tracking, :payment, :recurring_donation)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.prepare_donation_params(donation)
|
|
|
|
nonprofit = donation.nonprofit
|
|
|
|
tracking = donation.tracking
|
|
|
|
campaign = donation.campaign
|
|
|
|
recurring = donation.recurring_donation
|
|
|
|
|
|
|
|
action_type = :donate
|
2019-07-30 21:29:24 +00:00
|
|
|
action_technical_type = 'cc.wemove.eu:donate'
|
2018-03-25 17:30:42 +00:00
|
|
|
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: [
|
2019-07-30 21:29:24 +00:00
|
|
|
{ zip: supporter.zip_code, country: supporter.country }
|
|
|
|
]
|
2018-03-25 17:30:42 +00:00
|
|
|
}
|
|
|
|
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}",
|
2019-07-30 21:29:24 +00:00
|
|
|
type: donation.recurring ? 'recurring' : 'single'
|
2018-03-25 17:30:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if donation.card_id
|
2019-07-30 21:29:24 +00:00
|
|
|
data = common_data.merge(
|
|
|
|
payment_processor: 'stripe',
|
2018-03-25 17:30:42 +00:00
|
|
|
amount_charged: donation.payment.charge.amount / 100.0,
|
|
|
|
transaction_id: donation.payment.charge.stripe_charge_id,
|
2019-07-30 21:29:24 +00:00
|
|
|
status: donation.payment.charge.paid? ? 'success' : 'not_paid'
|
|
|
|
)
|
2018-03-25 17:30:42 +00:00
|
|
|
elsif donation.direct_debit_detail_id
|
2019-07-30 21:29:24 +00:00
|
|
|
data = common_data.merge(
|
|
|
|
payment_processor: 'sepa',
|
2018-03-25 17:30:42 +00:00
|
|
|
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,
|
2019-07-30 21:29:24 +00:00
|
|
|
status: 'success'
|
|
|
|
)
|
2018-03-25 17:30:42 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
data
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.recurring_data(recurring)
|
|
|
|
{
|
|
|
|
id: recurring.id,
|
|
|
|
start: recurring.start_date,
|
|
|
|
time_unit: recurring.time_unit,
|
2019-07-30 21:29:24 +00:00
|
|
|
active: recurring.active
|
2018-03-25 17:30:42 +00:00
|
|
|
}
|
|
|
|
end
|
2019-07-30 21:29:24 +00:00
|
|
|
|
2018-03-25 17:30:42 +00:00
|
|
|
def self.tracking_data(tracking)
|
|
|
|
{
|
|
|
|
source: tracking.utm_source,
|
|
|
|
medium: tracking.utm_medium,
|
|
|
|
campaign: tracking.utm_campaign,
|
|
|
|
content: tracking.utm_content
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|