houdini/lib/insert/insert_payout.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

93 lines
4.3 KiB
Ruby

# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
# Create a new payout
require 'psql'
require 'qexpr'
require 'query/query_payments'
require 'update/update_charges'
require 'update/update_refunds'
require 'update/update_disputes'
require 'param_validation'
module InsertPayout
# Pass in the following inside the data hash:
# - stripe_account_id
# - email
# - user_ip
# - bank_name
# options hash can have a :date (before date) for only paying out funds before a certain date (useful for only disbursing the prev month)
def self.with_stripe(np_id, data, options={})
bigger_data = (data ? data : {}).merge(np_id: np_id)
ParamValidation.new(bigger_data, {
np_id: {required: true, is_integer: true},
stripe_account_id: {not_blank: true, required: true},
email: {not_blank: true, required: true},
user_ip: {not_blank: true, required: true},
bank_name: {not_blank: true, required: true}
})
options ||= {}
entities = RetrieveActiveRecordItems.retrieve_from_keys(bigger_data, Nonprofit => :np_id)
payment_ids = QueryPayments.ids_for_payout(np_id, options)
if payment_ids.count < 1
raise ArgumentError.new("No payments are available for disbursal on this account.")
end
totals = QueryPayments.get_payout_totals(payment_ids)
nonprofit_currency = entities[:np_id].currency
now = Time.current
begin
stripe_transfer = StripeUtils.create_transfer(totals['net_amount'], data[:stripe_account_id], nonprofit_currency)
Psql.transaction do
# Create the Transfer on Stripe
# Retrieve all payments with available charges and undisbursed refunds
# Mark all the above payments as disbursed
UpdateCharges.disburse_all_with_payments(payment_ids)
# Mark all the above refunds as disbursed
UpdateRefunds.disburse_all_with_payments(payment_ids)
# Mark all disputes as lost_and_paid
UpdateDisputes.disburse_all_with_payments(payment_ids)
# Get gross total, total fees, net total, and total count
# Create the payout record (whether it succeeded on Stripe or not)
payout = Psql.execute(
Qexpr.new.insert(:payouts, [{
net_amount: totals['net_amount'],
nonprofit_id: np_id,
failure_message: stripe_transfer['failure_message'],
status: stripe_transfer.status,
fee_total: totals['fee_total'],
gross_amount: totals['gross_amount'],
email: data[:email],
count: totals['count'],
stripe_transfer_id: stripe_transfer.id,
user_ip: data[:user_ip],
ach_fee: 0,
bank_name: data[:bank_name]}])
.returning('id', 'net_amount', 'nonprofit_id', 'created_at', 'updated_at', 'status', 'fee_total', 'gross_amount', 'email', 'count', 'stripe_transfer_id', 'user_ip', 'ach_fee', 'bank_name')
).first
# Create PaymentPayout records linking all the payments to the payout
pps = Psql.execute(Qexpr.new.insert('payment_payouts', payment_ids.map{|id| {payment_id: id.to_i}}, {common_data: {payout_id: payout['id'].to_i}}))
NonprofitMailer.delay.pending_payout_notification(payout['id'].to_i)
return payout
end
rescue Stripe::StripeError => e
payout = Psql.execute(
Qexpr.new.insert(:payouts, [{
net_amount: totals['net_amount'],
nonprofit_id: np_id,
failure_message: e.message,
status: 'failed',
fee_total: totals['fee_total'],
gross_amount: totals['gross_amount'],
email: data[:email],
count: totals['count'],
stripe_transfer_id: nil,
user_ip: data[:user_ip],
ach_fee: 0,
bank_name: data[:bank_name]}])
.returning('id', 'net_amount', 'nonprofit_id', 'created_at', 'updated_at', 'status', 'fee_total', 'gross_amount', 'email', 'count', 'stripe_transfer_id', 'user_ip', 'ach_fee', 'bank_name')
).first
return payout
end
end
end