Filtering by event or campaign will include refunds now
This commit is contained in:
parent
e3fb6e6c92
commit
bf5b10f280
12 changed files with 465 additions and 19 deletions
2
Gemfile
2
Gemfile
|
@ -42,7 +42,7 @@ gem 'font_assets'
|
||||||
|
|
||||||
# Database (postgres)
|
# Database (postgres)
|
||||||
gem 'pg' # Postgresql
|
gem 'pg' # Postgresql
|
||||||
gem 'qx', git: 'https://github.com/commitchange/ruby-qx.git'
|
gem 'qx', git: 'https://github.com/ericschultz/ruby-qx.git'
|
||||||
gem 'dalli'
|
gem 'dalli'
|
||||||
gem 'memcachier'
|
gem 'memcachier'
|
||||||
|
|
||||||
|
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -5,14 +5,6 @@ GIT
|
||||||
param_validation (0.0.2)
|
param_validation (0.0.2)
|
||||||
chronic
|
chronic
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/commitchange/ruby-qx.git
|
|
||||||
revision: 3582c9a3c5d03f23480bc9b8ff1948a351ed8d6c
|
|
||||||
specs:
|
|
||||||
qx (0.1.1)
|
|
||||||
activerecord (>= 3.0)
|
|
||||||
colorize (~> 0.8)
|
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/commitchange/stripe-ruby-mock.git
|
remote: https://github.com/commitchange/stripe-ruby-mock.git
|
||||||
revision: ee4471a8f654672d5596218c2b68a2913ea3f4cc
|
revision: ee4471a8f654672d5596218c2b68a2913ea3f4cc
|
||||||
|
@ -32,6 +24,14 @@ GIT
|
||||||
grape (> 0.7)
|
grape (> 0.7)
|
||||||
rails (> 3.2, < 5)
|
rails (> 3.2, < 5)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/ericschultz/ruby-qx.git
|
||||||
|
revision: 179467cd4a8c791beb36428975c287acc11b98b2
|
||||||
|
specs:
|
||||||
|
qx (0.1.1)
|
||||||
|
activerecord (>= 3.0)
|
||||||
|
colorize (~> 0.8)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/ruby-grape/grape-entity.git
|
remote: https://github.com/ruby-grape/grape-entity.git
|
||||||
revision: 0e04aa561373b510c2486282979085eaef2ae663
|
revision: 0e04aa561373b510c2486282979085eaef2ae663
|
||||||
|
|
6
db/migrate/20180713213748_add_charge_id_indexes.rb
Normal file
6
db/migrate/20180713213748_add_charge_id_indexes.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class AddChargeIdIndexes < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_index :refunds, :charge_id
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
5
db/migrate/20180713215825_add_payment_id_to_tickets.rb
Normal file
5
db/migrate/20180713215825_add_payment_id_to_tickets.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPaymentIdToTickets < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_index :tickets, :payment_id
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20180713220028_add_indexes_to_refunds.rb
Normal file
5
db/migrate/20180713220028_add_indexes_to_refunds.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddIndexesToRefunds < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_index :refunds, :payment_id
|
||||||
|
end
|
||||||
|
end
|
|
@ -3162,6 +3162,20 @@ CREATE INDEX index_exports_on_nonprofit_id ON public.exports USING btree (nonpro
|
||||||
CREATE INDEX index_exports_on_user_id ON public.exports USING btree (user_id);
|
CREATE INDEX index_exports_on_user_id ON public.exports USING btree (user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_refunds_on_charge_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_refunds_on_charge_id ON public.refunds USING btree (charge_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_refunds_on_payment_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_refunds_on_payment_id ON public.refunds USING btree (payment_id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_sessions_on_session_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_sessions_on_session_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -3232,6 +3246,13 @@ CREATE INDEX index_supporters_on_name ON public.supporters USING btree (name);
|
||||||
CREATE INDEX index_tickets_on_event_id ON public.tickets USING btree (event_id);
|
CREATE INDEX index_tickets_on_event_id ON public.tickets USING btree (event_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_tickets_on_payment_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_tickets_on_payment_id ON public.tickets USING btree (payment_id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_tickets_on_supporter_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_tickets_on_supporter_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -4300,3 +4321,9 @@ INSERT INTO schema_migrations (version) VALUES ('20180608205049');
|
||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20180608212658');
|
INSERT INTO schema_migrations (version) VALUES ('20180608212658');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20180713213748');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20180713215825');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20180713220028');
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ module InsertRefunds
|
||||||
def self.with_stripe(charge, h)
|
def self.with_stripe(charge, h)
|
||||||
ParamValidation.new(charge, {
|
ParamValidation.new(charge, {
|
||||||
payment_id: {required: true, is_integer: true},
|
payment_id: {required: true, is_integer: true},
|
||||||
stripe_charge_id: {required: true, format: /^ch_.*$/},
|
stripe_charge_id: {required: true, format: /^(test_)?ch_.*$/},
|
||||||
amount: {required: true, is_integer: true, min: 1},
|
amount: {required: true, is_integer: true, min: 1},
|
||||||
id: {required: true, is_integer: true},
|
id: {required: true, is_integer: true},
|
||||||
nonprofit_id: {required: true, is_integer: true},
|
nonprofit_id: {required: true, is_integer: true},
|
||||||
|
|
|
@ -105,13 +105,49 @@ module QueryPayments
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# we must provide payments.*, supporters.*, donations.*, associated event_id, associated campaign_id
|
||||||
def self.full_search_expr(npo_id, query)
|
def self.full_search_expr(npo_id, query)
|
||||||
expr = Qexpr.new.from('payments')
|
expr = Qexpr.new.from('payments')
|
||||||
.left_outer_join('supporters', "supporters.id=payments.supporter_id")
|
.left_outer_join('supporters', "supporters.id=payments.supporter_id")
|
||||||
.left_outer_join('donations', 'donations.id=payments.donation_id' )
|
.left_outer_join('donations', 'donations.id=payments.donation_id' )
|
||||||
.where('payments.nonprofit_id=$id', id: npo_id.to_i)
|
.join("(#{select_to_filter_search(npo_id, query)}) AS \"filtered_payments\"", 'payments.id = filtered_payments.id')
|
||||||
.order_by('payments.date DESC')
|
.order_by('payments.date DESC')
|
||||||
|
|
||||||
|
if ['asc', 'desc'].include? query[:sort_amount]
|
||||||
|
expr = expr.order_by("payments.gross_amount #{query[:sort_amount]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_date]
|
||||||
|
expr = expr.order_by("payments.date #{query[:sort_date]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_name]
|
||||||
|
expr = expr.order_by("coalesce(NULLIF(supporters.name, ''), NULLIF(supporters.email, '')) #{query[:sort_name]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_type]
|
||||||
|
expr = expr.order_by("payments.kind #{query[:sort_type]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_towards]
|
||||||
|
expr = expr.order_by("NULLIF(payments.towards, '') #{query[:sort_towards]}")
|
||||||
|
end
|
||||||
|
|
||||||
|
return expr
|
||||||
|
end
|
||||||
|
|
||||||
|
# perform the search but only get the relevant payment_ids
|
||||||
|
def self.select_to_filter_search(npo_id, query)
|
||||||
|
|
||||||
|
inner_donation_search = Qexpr.new.select('donations.*').from('donations')
|
||||||
|
if (query[:event_id].present?)
|
||||||
|
inner_donation_search = inner_donation_search.where('donations.event_id=$id', id: query[:event_id])
|
||||||
|
end
|
||||||
|
if (query[:campaign_id].present?)
|
||||||
|
inner_donation_search = inner_donation_search.where('donations.campaign_id=$id', id: query[:campaign_id])
|
||||||
|
end
|
||||||
|
expr = Qexpr.new.select('payments.id').from('payments')
|
||||||
|
.left_outer_join('supporters', "supporters.id=payments.supporter_id")
|
||||||
|
.left_outer_join(inner_donation_search.as('donations'), 'donations.id=payments.donation_id' )
|
||||||
|
.where('payments.nonprofit_id=$id', id: npo_id.to_i)
|
||||||
|
|
||||||
|
|
||||||
if query[:search].present?
|
if query[:search].present?
|
||||||
expr = SearchVector.query(query[:search], expr)
|
expr = SearchVector.query(query[:search], expr)
|
||||||
end
|
end
|
||||||
|
@ -156,16 +192,105 @@ module QueryPayments
|
||||||
end
|
end
|
||||||
if query[:campaign_id].present?
|
if query[:campaign_id].present?
|
||||||
expr = expr
|
expr = expr
|
||||||
.left_outer_join("campaigns", "campaigns.id=donations.campaign_id" )
|
.left_outer_join("campaigns", "campaigns.id=donations.campaign_id" )
|
||||||
.where("campaigns.id=$id", id: query[:campaign_id])
|
.where("campaigns.id=$id", id: query[:campaign_id])
|
||||||
end
|
end
|
||||||
if query[:event_id].present?
|
if query[:event_id].present?
|
||||||
tickets_subquery = Qexpr.new.select("payment_id", "MAX(event_id) AS event_id").from("tickets").group_by("payment_id").as("tix")
|
tickets_subquery = Qexpr.new.select("payment_id", "MAX(event_id) AS event_id").from("tickets").where('tickets.event_id=$event_id', event_id: query[:event_id]).group_by("payment_id").as("tix")
|
||||||
expr = expr
|
expr = expr
|
||||||
.left_outer_join(tickets_subquery, "tix.payment_id=payments.id")
|
.left_outer_join(tickets_subquery, "tix.payment_id=payments.id")
|
||||||
.where("tix.event_id=$id OR donations.event_id=$id", id: query[:event_id])
|
.where("tix.event_id=$id OR donations.event_id=$id", id: query[:event_id])
|
||||||
|
|
||||||
end
|
end
|
||||||
return expr
|
|
||||||
|
expr = expr
|
||||||
|
|
||||||
|
#we have the first part of the search. We need to create the second in certain situations
|
||||||
|
filtered_payment_id_search = expr.parse
|
||||||
|
|
||||||
|
if query[:event_id].present? || query[:campaign_id].present?
|
||||||
|
filtered_payment_id_search = filtered_payment_id_search + " UNION DISTINCT " + create_reverse_select(npo_id, query).parse
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
filtered_payment_id_search
|
||||||
|
end
|
||||||
|
|
||||||
|
# we use this when we need to get the refund info
|
||||||
|
def self.create_reverse_select(npo_id, query)
|
||||||
|
inner_donation_search = Qexpr.new.select('donations.*').from('donations')
|
||||||
|
if (query[:event_id].present?)
|
||||||
|
inner_donation_search = inner_donation_search.where('donations.event_id=$id', id: query[:event_id])
|
||||||
|
end
|
||||||
|
if (query[:campaign_id].present?)
|
||||||
|
inner_donation_search = inner_donation_search.where('donations.campaign_id=$id', id: query[:campaign_id])
|
||||||
|
end
|
||||||
|
expr = Qexpr.new.select('payments.id').from('payments')
|
||||||
|
.left_outer_join('supporters', "supporters.id=payments.supporter_id")
|
||||||
|
.left_outer_join('refunds', 'payments.id=refunds.payment_id')
|
||||||
|
.left_outer_join('charges', 'refunds.charge_id=charges.id')
|
||||||
|
.left_outer_join('payments AS payments_orig', 'payments_orig.id=charges.payment_id')
|
||||||
|
.left_outer_join(inner_donation_search.as('donations'), 'donations.id=payments_orig.donation_id' )
|
||||||
|
.where('payments.nonprofit_id=$id', id: npo_id.to_i)
|
||||||
|
|
||||||
|
|
||||||
|
if query[:search].present?
|
||||||
|
expr = SearchVector.query(query[:search], expr)
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_amount]
|
||||||
|
expr = expr.order_by("payments.gross_amount #{query[:sort_amount]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_date]
|
||||||
|
expr = expr.order_by("payments.date #{query[:sort_date]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_name]
|
||||||
|
expr = expr.order_by("coalesce(NULLIF(supporters.name, ''), NULLIF(supporters.email, '')) #{query[:sort_name]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_type]
|
||||||
|
expr = expr.order_by("payments.kind #{query[:sort_type]}")
|
||||||
|
end
|
||||||
|
if ['asc', 'desc'].include? query[:sort_towards]
|
||||||
|
expr = expr.order_by("NULLIF(payments.towards, '') #{query[:sort_towards]}")
|
||||||
|
end
|
||||||
|
if query[:after_date].present?
|
||||||
|
expr = expr.where('payments.date >= $date', date: query[:after_date])
|
||||||
|
end
|
||||||
|
if query[:before_date].present?
|
||||||
|
expr = expr.where('payments.date <= $date', date: query[:before_date])
|
||||||
|
end
|
||||||
|
if query[:amount_greater_than].present?
|
||||||
|
expr = expr.where('payments.gross_amount >= $amt', amt: query[:amount_greater_than].to_i * 100)
|
||||||
|
end
|
||||||
|
if query[:amount_less_than].present?
|
||||||
|
expr = expr.where('payments.gross_amount <= $amt', amt: query[:amount_less_than].to_i * 100)
|
||||||
|
end
|
||||||
|
if query[:year].present?
|
||||||
|
expr = expr.where("to_char(payments.date, 'YYYY')=$year", year: query[:year])
|
||||||
|
end
|
||||||
|
if query[:designation].present?
|
||||||
|
expr = expr.where("donations.designation @@ $s", s: "#{query[:designation]}")
|
||||||
|
end
|
||||||
|
if query[:dedication].present?
|
||||||
|
expr = expr.where("donations.dedication @@ $s", s: "#{query[:dedication]}")
|
||||||
|
end
|
||||||
|
if query[:donation_type].present?
|
||||||
|
expr = expr.where('payments.kind IN ($kinds)', kinds: query[:donation_type].split(','))
|
||||||
|
end
|
||||||
|
if query[:campaign_id].present?
|
||||||
|
expr = expr
|
||||||
|
.left_outer_join("campaigns", "campaigns.id=donations.campaign_id" )
|
||||||
|
.where("campaigns.id=$id", id: query[:campaign_id])
|
||||||
|
end
|
||||||
|
if query[:event_id].present?
|
||||||
|
tickets_subquery = Qexpr.new.select("payment_id", "MAX(event_id) AS event_id").from("tickets").where('tickets.event_id=$event_id', event_id: query[:event_id]).group_by("payment_id").as("tix")
|
||||||
|
expr = expr
|
||||||
|
.left_outer_join(tickets_subquery, "tix.payment_id=payments_orig.id")
|
||||||
|
.where("tix.event_id=$id OR donations.event_id=$id", id: query[:event_id])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
expr
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.for_export_enumerable(npo_id, query, chunk_limit=35000)
|
def self.for_export_enumerable(npo_id, query, chunk_limit=35000)
|
||||||
|
|
|
@ -8,6 +8,10 @@ describe InsertDonation do
|
||||||
Settings.payment_provider.stripe_connect = true
|
Settings.payment_provider.stripe_connect = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
after(:each) {
|
||||||
|
Settings.reload!
|
||||||
|
}
|
||||||
|
|
||||||
include_context :shared_rd_donation_value_context
|
include_context :shared_rd_donation_value_context
|
||||||
|
|
||||||
describe 'param validation' do
|
describe 'param validation' do
|
||||||
|
|
|
@ -164,4 +164,235 @@ describe QueryPayments do
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.full_search' do
|
||||||
|
|
||||||
|
include_context :shared_rd_donation_value_context
|
||||||
|
before(:each) {
|
||||||
|
nonprofit.stripe_account_id = Stripe::Account.create()['id']
|
||||||
|
nonprofit.save!
|
||||||
|
card.stripe_customer_id = 'some other id'
|
||||||
|
cust = Stripe::Customer.create()
|
||||||
|
card.stripe_customer_id = cust['id']
|
||||||
|
card.save!
|
||||||
|
expect(Stripe::Charge).to receive(:create).exactly(3).times.and_wrap_original {|m, *args| a = m.call(*args);
|
||||||
|
@stripe_charge_id = a['id']
|
||||||
|
a
|
||||||
|
}
|
||||||
|
|
||||||
|
allow(QueueDonations).to receive(:execute_for_donation)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:charge_amount_small) { 200}
|
||||||
|
let(:charge_amount_medium) { 400}
|
||||||
|
let(:charge_amount_large) { 600}
|
||||||
|
|
||||||
|
def generate_donation(h)
|
||||||
|
token = h[:token]
|
||||||
|
date = h[:date]
|
||||||
|
amount = h[:amount]
|
||||||
|
|
||||||
|
input = {amount: amount,
|
||||||
|
nonprofit_id: nonprofit.id,
|
||||||
|
supporter_id: supporter.id,
|
||||||
|
token: token,
|
||||||
|
|
||||||
|
date: date,
|
||||||
|
dedication: 'dedication',
|
||||||
|
designation: 'designation'}
|
||||||
|
if h[:event_id]
|
||||||
|
input[:event_id] = h[:event_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
if h[:campaign_id]
|
||||||
|
input[:campaign_id] = h[:campaign_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
InsertDonation.with_stripe(input)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'general donations' do
|
||||||
|
let(:donation_result_yesterday) {
|
||||||
|
generate_donation(amount: charge_amount_small,
|
||||||
|
|
||||||
|
token: source_tokens[0].token,
|
||||||
|
date: (Time.now - 1.day).to_s)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_today) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_medium,
|
||||||
|
|
||||||
|
token: source_tokens[1].token,
|
||||||
|
|
||||||
|
date: (Time.now).to_s
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_tomorrow) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_large,
|
||||||
|
|
||||||
|
token: source_tokens[2].token,
|
||||||
|
date: (Time.now - 1.day).to_s
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let (:first_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 100}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:second_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 50}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
it 'empty filter returns all' do
|
||||||
|
donation_result_yesterday
|
||||||
|
donation_result_today
|
||||||
|
donation_result_tomorrow
|
||||||
|
first_refund_of_yesterday
|
||||||
|
second_refund_of_yesterday
|
||||||
|
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, {})
|
||||||
|
|
||||||
|
expect(result[:data].count).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'event donations' do
|
||||||
|
let(:donation_result_yesterday) {
|
||||||
|
generate_donation(amount: charge_amount_small,
|
||||||
|
event_id: event.id,
|
||||||
|
token: source_tokens[0].token,
|
||||||
|
date: (Time.now - 1.day).to_s)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_today) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_medium,
|
||||||
|
event_id: event.id,
|
||||||
|
token: source_tokens[1].token,
|
||||||
|
|
||||||
|
date: (Time.now).to_s
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_tomorrow) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_large,
|
||||||
|
|
||||||
|
token: source_tokens[2].token,
|
||||||
|
date: (Time.now - 1.day).to_s
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let (:first_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 100}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:second_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 50}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'search includes refunds for that event ' do
|
||||||
|
donation_result_yesterday
|
||||||
|
donation_result_today
|
||||||
|
donation_result_tomorrow
|
||||||
|
first_refund_of_yesterday
|
||||||
|
second_refund_of_yesterday
|
||||||
|
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, {event_id: event.id})
|
||||||
|
|
||||||
|
expect(result[:data].count).to eq 4
|
||||||
|
expect(result[:data]).to_not satisfy {|i| i.any?{|j| j['id'] == donation_result_tomorrow['payment']['id']}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'campaign donations' do
|
||||||
|
let(:donation_result_yesterday) {
|
||||||
|
generate_donation(amount: charge_amount_small,
|
||||||
|
campaign_id:campaign.id,
|
||||||
|
token: source_tokens[0].token,
|
||||||
|
date: (Time.now - 1.day).to_s)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_today) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_medium,
|
||||||
|
campaign_id:campaign.id,
|
||||||
|
token: source_tokens[1].token,
|
||||||
|
|
||||||
|
date: (Time.now).to_s
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:donation_result_tomorrow) {
|
||||||
|
|
||||||
|
generate_donation(amount: charge_amount_large,
|
||||||
|
|
||||||
|
token: source_tokens[2].token,
|
||||||
|
date: (Time.now - 1.day).to_s
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let (:first_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 100}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let(:second_refund_of_yesterday) {
|
||||||
|
charge = donation_result_yesterday['charge']
|
||||||
|
|
||||||
|
InsertRefunds.with_stripe(charge.attributes, {amount: 50}.with_indifferent_access)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
it 'search includes refunds for that campaign ' do
|
||||||
|
donation_result_yesterday
|
||||||
|
donation_result_today
|
||||||
|
donation_result_tomorrow
|
||||||
|
first_refund_of_yesterday
|
||||||
|
second_refund_of_yesterday
|
||||||
|
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, {campaign_id: campaign.id})
|
||||||
|
|
||||||
|
expect(result[:data].count).to eq 4
|
||||||
|
expect(result[:data]).to_not satisfy {|i| i.any?{|j| j['id'] == donation_result_tomorrow['payment']['id']}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
require 'stripe_mock'
|
require 'stripe_mock'
|
||||||
|
|
||||||
RSpec.shared_context :shared_donation_charge_context do
|
RSpec.shared_context :shared_donation_charge_context do
|
||||||
let(:nonprofit) { force_create(:nonprofit, name: "nonprofit name")}
|
let(:nonprofit) { force_create(:nonprofit, name: "nonprofit name", slug: 'nonprofit_nameo')}
|
||||||
let(:other_nonprofit) { force_create(:nonprofit)}
|
let(:other_nonprofit) { force_create(:nonprofit)}
|
||||||
let(:supporter) {force_create(:supporter, :nonprofit => nonprofit, locale: 'locale_one')}
|
let(:supporter) {force_create(:supporter, :nonprofit => nonprofit, locale: 'locale_one')}
|
||||||
let(:other_nonprofit_supporter) { force_create(:supporter, nonprofit: other_nonprofit, locale: 'locale_two')}
|
let(:other_nonprofit_supporter) { force_create(:supporter, nonprofit: other_nonprofit, locale: 'locale_two')}
|
||||||
|
|
|
@ -6,7 +6,13 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
let(:fake_uuid) {"53a6bc06-0789-11e8-bb3f-f34cac607737"}
|
let(:fake_uuid) {"53a6bc06-0789-11e8-bb3f-f34cac607737"}
|
||||||
let(:valid_uuid) {'fcf61bac-078a-11e8-aa53-cba5bdb8dcdd'}
|
let(:valid_uuid) {'fcf61bac-078a-11e8-aa53-cba5bdb8dcdd'}
|
||||||
let(:other_uuid) {'a713018c-078f-11e8-ae3b-bf5007844fea'}
|
let(:other_uuid) {'a713018c-078f-11e8-ae3b-bf5007844fea'}
|
||||||
let(:source_token) {force_create(:source_token, tokenizable: card, expiration: Time.now + 1.day, max_uses: 1, token: valid_uuid)}
|
let(:source_token) {force_create(:source_token, tokenizable: card, expiration: Time.now + 1.day, max_uses: 1, token: valid_uuid) }
|
||||||
|
let(:source_tokens) {
|
||||||
|
(0..10).map { |i|
|
||||||
|
force_create(:source_token, tokenizable: card, expiration: Time.now + 1.day, max_uses: 1, token: SecureRandom.uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let(:other_source_token) {force_create(:source_token, tokenizable: card_for_other_supporter, expiration: Time.now + 1.day, max_uses: 1, token: other_uuid)}
|
let(:other_source_token) {force_create(:source_token, tokenizable: card_for_other_supporter, expiration: Time.now + 1.day, max_uses: 1, token: other_uuid)}
|
||||||
|
|
||||||
let(:charge_amount) {100}
|
let(:charge_amount) {100}
|
||||||
|
@ -147,6 +153,11 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_expected_refund(data={})
|
||||||
|
result = {}.with_indifferent_access
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
def validation_unauthorized
|
def validation_unauthorized
|
||||||
expect(QuerySourceToken).to receive(:get_and_increment_source_token).with(fake_uuid, nil).and_raise(AuthenticationError)
|
expect(QuerySourceToken).to receive(:get_and_increment_source_token).with(fake_uuid, nil).and_raise(AuthenticationError)
|
||||||
expect {yield()}.to raise_error {|e|
|
expect {yield()}.to raise_error {|e|
|
||||||
|
@ -382,6 +393,24 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def before_each_successful_refund()
|
||||||
|
expect(InsertRefund).to receive(:with_stripe).and_wrap_original do |m, *args|
|
||||||
|
result = m.call(*args);
|
||||||
|
@all_refunds&.push(result) || @all_refunds = [result]
|
||||||
|
@fifo_refunds&.unshift(result) || @fifo_refunds = [ result]
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(Stripe::Refund).to receive(:create).and_wrap_original do |m, *args|
|
||||||
|
a = m.call(*args);
|
||||||
|
@stripe_refund_ids&.unshift(a['id']) || @stripe_refund_ids = [a['id']];
|
||||||
|
a
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def before_each_sepa_success()
|
def before_each_sepa_success()
|
||||||
expect(InsertDonation).to receive(:insert_donation).and_wrap_original do |m, *args|
|
expect(InsertDonation).to receive(:insert_donation).and_wrap_original do |m, *args|
|
||||||
result = m.call(*args);
|
result = m.call(*args);
|
||||||
|
@ -406,6 +435,8 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
if (data[:recurring_donation])
|
if (data[:recurring_donation])
|
||||||
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_campaign_donation(data = {})
|
def process_campaign_donation(data = {})
|
||||||
|
@ -422,6 +453,7 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
if (data[:recurring_donation])
|
if (data[:recurring_donation])
|
||||||
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
||||||
end
|
end
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_general_donation(data = {})
|
def process_general_donation(data = {})
|
||||||
|
@ -447,6 +479,17 @@ RSpec.shared_context :shared_rd_donation_value_context do
|
||||||
if (data[:recurring_donation])
|
if (data[:recurring_donation])
|
||||||
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
expect(result['recurring_donation'].attributes).to eq expected[:recurring_donation]
|
||||||
end
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_general_refund(data = {})
|
||||||
|
result = yield
|
||||||
|
|
||||||
|
expected = generate_expected_refund()
|
||||||
|
|
||||||
|
expect(result['payment']).to eq expected[:payment]
|
||||||
|
expect(result['refund']).to eq expected[:refund]
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
def nil_or_true(item)
|
def nil_or_true(item)
|
||||||
|
|
Loading…
Reference in a new issue