Considering timezone when querying payments
This commit is contained in:
parent
f56ba93e71
commit
eaa2b40499
2 changed files with 74 additions and 5 deletions
|
@ -83,7 +83,10 @@ module QueryPayments
|
||||||
'supporters.name',
|
'supporters.name',
|
||||||
'supporters.email',
|
'supporters.email',
|
||||||
'payments.gross_amount',
|
'payments.gross_amount',
|
||||||
'payments.date'
|
'timezone(
|
||||||
|
COALESCE(nonprofits.timezone, \'UTC\'),
|
||||||
|
timezone(\'UTC\', payments.date)
|
||||||
|
) as date'
|
||||||
)
|
)
|
||||||
|
|
||||||
payments = Psql.execute(expr.limit(limit).offset(offset).parse)
|
payments = Psql.execute(expr.limit(limit).offset(offset).parse)
|
||||||
|
@ -110,6 +113,7 @@ module QueryPayments
|
||||||
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')
|
||||||
|
.inner_join('nonprofits', 'nonprofits.id=payments.nonprofit_id')
|
||||||
.left_outer_join('donations', 'donations.id=payments.donation_id')
|
.left_outer_join('donations', 'donations.id=payments.donation_id')
|
||||||
.join("(#{select_to_filter_search(npo_id, query)}) AS \"filtered_payments\"", 'payments.id = filtered_payments.id')
|
.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')
|
||||||
|
@ -145,6 +149,7 @@ module QueryPayments
|
||||||
end
|
end
|
||||||
expr = Qexpr.new.select('payments.id').from('payments')
|
expr = Qexpr.new.select('payments.id').from('payments')
|
||||||
.left_outer_join('supporters', 'supporters.id=payments.supporter_id')
|
.left_outer_join('supporters', 'supporters.id=payments.supporter_id')
|
||||||
|
.inner_join('nonprofits', 'nonprofits.id=payments.nonprofit_id')
|
||||||
.left_outer_join(inner_donation_search.as('donations'), 'donations.id=payments.donation_id')
|
.left_outer_join(inner_donation_search.as('donations'), 'donations.id=payments.donation_id')
|
||||||
.where('payments.nonprofit_id=$id', id: npo_id.to_i)
|
.where('payments.nonprofit_id=$id', id: npo_id.to_i)
|
||||||
|
|
||||||
|
@ -165,10 +170,10 @@ module QueryPayments
|
||||||
expr = expr.order_by("NULLIF(payments.towards, '') #{query[:sort_towards]}")
|
expr = expr.order_by("NULLIF(payments.towards, '') #{query[:sort_towards]}")
|
||||||
end
|
end
|
||||||
if query[:after_date].present?
|
if query[:after_date].present?
|
||||||
expr = expr.where('payments.date >= $date', date: query[:after_date])
|
expr = expr.where('payments.date >= timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $date))', date: query[:after_date])
|
||||||
end
|
end
|
||||||
if query[:before_date].present?
|
if query[:before_date].present?
|
||||||
expr = expr.where('payments.date <= $date', date: query[:before_date])
|
expr = expr.where('payments.date <= timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $date))', date: query[:before_date])
|
||||||
end
|
end
|
||||||
if query[:amount_greater_than].present?
|
if query[:amount_greater_than].present?
|
||||||
expr = expr.where('payments.gross_amount >= $amt', amt: query[:amount_greater_than].to_i * 100)
|
expr = expr.where('payments.gross_amount >= $amt', amt: query[:amount_greater_than].to_i * 100)
|
||||||
|
@ -177,7 +182,14 @@ module QueryPayments
|
||||||
expr = expr.where('payments.gross_amount <= $amt', amt: query[:amount_less_than].to_i * 100)
|
expr = expr.where('payments.gross_amount <= $amt', amt: query[:amount_less_than].to_i * 100)
|
||||||
end
|
end
|
||||||
if query[:year].present?
|
if query[:year].present?
|
||||||
expr = expr.where("to_char(payments.date, 'YYYY')=$year", year: query[:year])
|
expr = expr
|
||||||
|
.where(
|
||||||
|
"to_char(timezone(
|
||||||
|
COALESCE(nonprofits.timezone, \'UTC\'),
|
||||||
|
timezone(\'UTC\', payments.date)
|
||||||
|
), 'YYYY')=$year",
|
||||||
|
year: (query[:year]).to_s
|
||||||
|
)
|
||||||
end
|
end
|
||||||
if query[:designation].present?
|
if query[:designation].present?
|
||||||
expr = expr.where('donations.designation @@ $s', s: (query[:designation]).to_s)
|
expr = expr.where('donations.designation @@ $s', s: (query[:designation]).to_s)
|
||||||
|
@ -332,7 +344,7 @@ module QueryPayments
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.export_selects
|
def self.export_selects
|
||||||
["to_char(payments.date::timestamptz, 'YYYY-MM-DD HH24:MI:SS TZ') AS date",
|
["to_char(payments.date::timestamptz at time zone COALESCE(nonprofits.timezone, \'UTC\'), 'YYYY-MM-DD HH24:MI:SS TZ') AS date",
|
||||||
'(payments.gross_amount / 100.0)::money::text AS gross_amount',
|
'(payments.gross_amount / 100.0)::money::text AS gross_amount',
|
||||||
'(payments.fee_total / 100.0)::money::text AS fee_total',
|
'(payments.fee_total / 100.0)::money::text AS fee_total',
|
||||||
'(payments.net_amount / 100.0)::money::text AS net_amount',
|
'(payments.net_amount / 100.0)::money::text AS net_amount',
|
||||||
|
|
|
@ -241,6 +241,63 @@ describe QueryPayments do
|
||||||
|
|
||||||
expect(result[:data].count).to eq 5
|
expect(result[:data].count).to eq 5
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'considering the nonprofit timezone on the query result' do
|
||||||
|
before do
|
||||||
|
donation_result_today
|
||||||
|
first_refund_of_yesterday
|
||||||
|
second_refund_of_yesterday
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'when the nonprofit does not have a timezone it considers UTC as default' do
|
||||||
|
donation_result_tomorrow
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, {})
|
||||||
|
expect(result[:data].first['date']).to eq (Time.now).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the nonprofit has a timezone' do
|
||||||
|
before do
|
||||||
|
nonprofit.update(timezone: 'America/New_York')
|
||||||
|
allow(QuerySourceToken)
|
||||||
|
.to receive(:get_and_increment_source_token)
|
||||||
|
.and_return(source_tokens[0])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the corresponding time' do
|
||||||
|
donation_result_tomorrow
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, {})
|
||||||
|
expect(result[:data].first['date']).to eq ((Time.now) - 4.hours).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds the payments on dates after the specified dates' do
|
||||||
|
donation_result_tomorrow
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, { after_date: Time.now - 4.hours })
|
||||||
|
expect(result[:data].count).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds the payments on dates before the specified dates' do
|
||||||
|
donation_result_tomorrow
|
||||||
|
result = QueryPayments::full_search(nonprofit.id, { before_date: Time.now })
|
||||||
|
expect(result[:data].count).to eq 5
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds the payments of an specific year' do
|
||||||
|
# creating a payment at 1 AM UTC from january 2020
|
||||||
|
# should not be included in the 2020 query if we are at America/New_York
|
||||||
|
Timecop.freeze(2020,1,1,1,0,0, "+00:00")
|
||||||
|
donation =
|
||||||
|
generate_donation(
|
||||||
|
amount: charge_amount_large,
|
||||||
|
token: source_tokens[2].token,
|
||||||
|
date: Time.now.to_s
|
||||||
|
)
|
||||||
|
result_for_2020 = QueryPayments::full_search(nonprofit.id, { year: '2020' })
|
||||||
|
result_for_2019 = QueryPayments::full_search(nonprofit.id, { year: '2019' })
|
||||||
|
expect(result_for_2019[:data].count).to eq 1
|
||||||
|
expect(result_for_2020[:data].count).to eq 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'event donations' do
|
describe 'event donations' do
|
||||||
|
|
Loading…
Reference in a new issue