Considering timezone when querying supporters
This commit is contained in:
parent
4a927c6c12
commit
f56ba93e71
2 changed files with 77 additions and 30 deletions
|
@ -92,7 +92,13 @@ module QuerySupporters
|
||||||
'supporters.is_unsubscribed_from_emails',
|
'supporters.is_unsubscribed_from_emails',
|
||||||
'supporters.id AS id',
|
'supporters.id AS id',
|
||||||
'tags.names AS tags',
|
'tags.names AS tags',
|
||||||
"to_char(payments.max_date, 'MM/DD/YY') AS last_contribution",
|
'to_char(
|
||||||
|
timezone(
|
||||||
|
COALESCE(nonprofits.timezone, \'UTC\'),
|
||||||
|
timezone(\'UTC\', payments.max_date)
|
||||||
|
),
|
||||||
|
\'MM/DD/YY\'
|
||||||
|
) AS last_contribution',
|
||||||
'payments.sum AS total_raised'
|
'payments.sum AS total_raised'
|
||||||
]
|
]
|
||||||
select += query[:select].split(',') if query[:select]
|
select += query[:select].split(',') if query[:select]
|
||||||
|
@ -173,28 +179,30 @@ module QuerySupporters
|
||||||
.group_by('tag_joins.supporter_id')
|
.group_by('tag_joins.supporter_id')
|
||||||
.as(:tags)
|
.as(:tags)
|
||||||
|
|
||||||
expr = Qx.select('supporters.id').from(:supporters)
|
expr = Qx.select('supporters.id')
|
||||||
.where(
|
.from(:supporters)
|
||||||
['supporters.nonprofit_id=$id', id: np_id.to_i],
|
.join('nonprofits', 'nonprofits.id=supporters.nonprofit_id')
|
||||||
['supporters.deleted != true']
|
.where(
|
||||||
)
|
['supporters.nonprofit_id=$id', id: np_id.to_i],
|
||||||
.left_join(
|
['supporters.deleted != true']
|
||||||
[tags_subquery, 'tags.supporter_id=supporters.id'],
|
)
|
||||||
[payments_subquery, 'payments.supporter_id=supporters.id']
|
.left_join(
|
||||||
)
|
[tags_subquery, 'tags.supporter_id=supporters.id'],
|
||||||
.order_by('payments.max_date DESC NULLS LAST')
|
[payments_subquery, 'payments.supporter_id=supporters.id']
|
||||||
|
)
|
||||||
|
.order_by('payments.max_date DESC NULLS LAST')
|
||||||
|
|
||||||
if query[:last_payment_after].present?
|
if query[:last_payment_after].present?
|
||||||
expr = expr.and_where('payments.max_date > $d', d: Chronic.parse(query[:last_payment_after]))
|
expr = expr.and_where("payments.max_date > timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: Chronic.parse(query[:last_payment_after]).beginning_of_day)
|
||||||
end
|
end
|
||||||
if query[:last_payment_before].present?
|
if query[:last_payment_before].present?
|
||||||
expr = expr.and_where('payments.max_date < $d', d: Chronic.parse(query[:last_payment_before]))
|
expr = expr.and_where("payments.max_date < timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: Chronic.parse(query[:last_payment_before]).beginning_of_day)
|
||||||
end
|
end
|
||||||
if query[:first_payment_after].present?
|
if query[:first_payment_after].present?
|
||||||
expr = expr.and_where('payments.min_date > $d', d: Chronic.parse(query[:first_payment_after]))
|
expr = expr.and_where("payments.min_date > timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: Chronic.parse(query[:first_payment_after]).beginning_of_day)
|
||||||
end
|
end
|
||||||
if query[:first_payment_before].present?
|
if query[:first_payment_before].present?
|
||||||
expr = expr.and_where('payments.min_date < $d', d: Chronic.parse(query[:first_payment_before]))
|
expr = expr.and_where("payments.min_date < timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: Chronic.parse(query[:first_payment_before]).beginning_of_day)
|
||||||
end
|
end
|
||||||
if query[:total_raised_greater_than].present?
|
if query[:total_raised_greater_than].present?
|
||||||
expr = expr.and_where('payments.sum > $amount', amount: query[:total_raised_greater_than].to_i * 100)
|
expr = expr.and_where('payments.sum > $amount', amount: query[:total_raised_greater_than].to_i * 100)
|
||||||
|
@ -204,15 +212,15 @@ module QuerySupporters
|
||||||
end
|
end
|
||||||
if %w[week month quarter year].include? query[:has_contributed_during]
|
if %w[week month quarter year].include? query[:has_contributed_during]
|
||||||
d = Time.current.send('beginning_of_' + query[:has_contributed_during])
|
d = Time.current.send('beginning_of_' + query[:has_contributed_during])
|
||||||
expr = expr.and_where('payments.max_date >= $d', d: d)
|
expr = expr.and_where("payments.max_date >= timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: d)
|
||||||
end
|
end
|
||||||
if %w[week month quarter year].include? query[:has_not_contributed_during]
|
if %w[week month quarter year].include? query[:has_not_contributed_during]
|
||||||
d = Time.current.send('beginning_of_' + query[:has_not_contributed_during])
|
d = Time.current.send('beginning_of_' + query[:has_not_contributed_during])
|
||||||
expr = expr.and_where('payments.count = 0 OR payments.max_date <= $d', d: d)
|
expr = expr.and_where("payments.count = 0 OR payments.max_date <= timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $d))", d: d)
|
||||||
end
|
end
|
||||||
if query[:MAX_payment_before].present?
|
if query[:MAX_payment_before].present?
|
||||||
date_ago = Timespan::TimeUnits[query[:MAX_payment_before]].utc
|
date_ago = Timespan::TimeUnits[query[:MAX_payment_before]].utc
|
||||||
expr = expr.and_where('payments.max_date < $date OR payments.count = 0', date: date_ago)
|
expr = expr.and_where("payments.max_date < timezone(COALESCE(nonprofits.timezone, \'UTC\'), timezone(\'UTC\', $date)) OR payments.count = 0", date: date_ago)
|
||||||
end
|
end
|
||||||
if query[:search].present?
|
if query[:search].present?
|
||||||
expr = expr.and_where(%(
|
expr = expr.and_where(%(
|
||||||
|
|
|
@ -11,20 +11,29 @@ describe QuerySupporters do
|
||||||
let(:campaign_gift_option_name) { 'theowthoinv' }
|
let(:campaign_gift_option_name) { 'theowthoinv' }
|
||||||
|
|
||||||
let(:np) { force_create(:nm_justice) }
|
let(:np) { force_create(:nm_justice) }
|
||||||
let(:supporter1) { force_create(:supporter, nonprofit: np) }
|
let(:supporter1) { force_create(:supporter, nonprofit: np, name: 'Cacau')}
|
||||||
let(:supporter2) { force_create(:supporter, nonprofit: np) }
|
let(:supporter2) { force_create(:supporter, nonprofit: np, name: 'Penelope')}
|
||||||
let(:campaign) { force_create(:campaign, nonprofit: np, slug: 'slug stuff') }
|
let(:campaign) { force_create(:campaign, nonprofit: np, slug: "slug stuff")}
|
||||||
let(:campaign_gift_option) { force_create(:campaign_gift_option, campaign: campaign, name: campaign_gift_option_name, amount_one_time: gift_level_one_time, amount_recurring: gift_level_recurring) }
|
let(:campaign_gift_option) { force_create(:campaign_gift_option, campaign: campaign, name: campaign_gift_option_name, amount_one_time: gift_level_one_time, amount_recurring: gift_level_recurring)}
|
||||||
let(:campaign_gift1) { force_create(:campaign_gift, campaign_gift_option: campaign_gift_option, donation: donation1) }
|
let(:campaign_gift1) { force_create(:campaign_gift, campaign_gift_option: campaign_gift_option, donation: donation1)}
|
||||||
let(:donation1) { force_create(:donation, amount: gift_level_one_time, campaign: campaign, supporter: supporter1) }
|
|
||||||
|
|
||||||
let(:payment1) { force_create(:payment, gross_amount: gift_level_one_time, donation: donation1) }
|
let(:payment_utc_time) { Time.new(2021, 10, 10, 1, 1, 0, "+00:00") }
|
||||||
|
let(:payment2_utc_time) { Time.new(2021, 1, 1, 1, 1, 0, "+00:00") }
|
||||||
|
|
||||||
let(:donation2) { force_create(:donation, amount: gift_level_changed_recurring, campaign: campaign, supporter: supporter2) }
|
let(:donation1) { force_create(:donation, amount: gift_level_one_time, campaign: campaign, supporter:supporter1, date: payment_utc_time)}
|
||||||
let(:payment2) { force_create(:payment, gross_amount: gift_level_recurring, donation: donation2) }
|
let(:donation4) { force_create(:donation, amount: gift_level_one_time, campaign: campaign, supporter:supporter1, date: payment2_utc_time)}
|
||||||
let(:payment3) { force_create(:payment, gross_amount: gift_level_changed_recurring, donation: donation2) }
|
let(:donation5) { force_create(:donation, amount: gift_level_one_time, campaign: campaign, supporter:supporter2, date: payment2_utc_time)}
|
||||||
let(:campaign_gift2) { force_create(:campaign_gift, campaign_gift_option: campaign_gift_option, donation: donation2) }
|
|
||||||
let(:recurring) { force_create(:recurring_donation, donation: donation2, amount: gift_level_changed_recurring) }
|
let(:payment1) {force_create(:payment, gross_amount: gift_level_one_time, donation: donation1, date: payment_utc_time)}
|
||||||
|
|
||||||
|
let(:donation2) {force_create(:donation, amount: gift_level_changed_recurring, campaign: campaign, supporter:supporter2)}
|
||||||
|
let(:payment2) {force_create(:payment, gross_amount: gift_level_recurring, donation: donation2)}
|
||||||
|
let(:payment4) {force_create(:payment, gross_amount: gift_level_one_time, donation: donation4, date: payment2_utc_time)}
|
||||||
|
let(:payment5) {force_create(:payment, gross_amount: gift_level_one_time, donation: donation5, date: payment2_utc_time)}
|
||||||
|
|
||||||
|
let(:payment3) {force_create(:payment, gross_amount: gift_level_changed_recurring, donation: donation2)}
|
||||||
|
let(:campaign_gift2) { force_create(:campaign_gift, campaign_gift_option: campaign_gift_option, donation: donation2)}
|
||||||
|
let(:recurring) {force_create(:recurring_donation, donation: donation2, amount: gift_level_changed_recurring)}
|
||||||
|
|
||||||
let(:note_content_1) do
|
let(:note_content_1) do
|
||||||
'CONTENT1'
|
'CONTENT1'
|
||||||
|
@ -95,4 +104,34 @@ describe QuerySupporters do
|
||||||
expect(lazy_enumerable.to_a.first).to eq ['Id', 'Email', 'Note Created At', 'Note Contents']
|
expect(lazy_enumerable.to_a.first).to eq ['Id', 'Email', 'Note Created At', 'Note Contents']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.full_search' do
|
||||||
|
before do
|
||||||
|
supporter1.payments = [payment1, payment4]
|
||||||
|
supporter2.payments = [payment5]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the UTC date when the timezone is not specified' do
|
||||||
|
result = QuerySupporters.full_search(np.id, { search: 'Cacau' })
|
||||||
|
expect(result[:data].first["last_contribution"]).to eq(payment_utc_time.strftime('%m/%d/%y'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the converted date when the timezone is specified' do
|
||||||
|
np.update(timezone: 'America/New_York')
|
||||||
|
result = QuerySupporters.full_search(np.id, { search: 'Cacau' })
|
||||||
|
expect(result[:data].first["last_contribution"]).to eq((payment_utc_time - 1.day).strftime('%m/%d/%y'))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds the payments on dates after the specified dates' do
|
||||||
|
np.update(timezone: 'America/New_York')
|
||||||
|
result = QuerySupporters.full_search(np.id, { last_payment_after: (payment2_utc_time + 1.day).to_s })
|
||||||
|
expect(result[:data].count).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds the payments on dates before the specified dates' do
|
||||||
|
np.update(timezone: 'America/New_York')
|
||||||
|
result = QuerySupporters.full_search(np.id, { last_payment_before: payment_utc_time.to_s })
|
||||||
|
expect(result[:data].count).to eq 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue