This repository has been archived by the owner on Feb 8, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 308
notify users of card charges #3301
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
cf2be43
Rough in charge notifications
chadwhitacre 284baf1
send email notifications at the end of payday
Changaco b0c6a8e
fix and complete email content
Changaco fb651a7
wire up email variables
Changaco 9e86733
add email simplate for failed charges
Changaco a64d326
add UI for the `notify_charge` setting
Changaco d73d422
fix test
Changaco c2cee2d
Here's a failing test for notify_participants
chadwhitacre bd5f789
modify test to avoid test fixtures and cover both email simplates
Changaco 047b0c2
fix payday notifications
Changaco 5973342
send notifications for successful charges by default
Changaco a5c9f8f
Show total amount charged, including processor fee
chadwhitacre 3e39acd
Tweak language of charge notifications
chadwhitacre f37d238
Link to receipt for successful charges
chadwhitacre cd7f418
fix text page of `charge_failed.spt`
Changaco c67335a
fix `record_exchange`: store the `error` in `note`
Changaco File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{{ _("Oh no! A problem supporting {0}!", top_tippee) }} | ||
|
||
[---] text/html | ||
{{ _("We tried to charge your credit card {0} today, to fund your ongoing support for {1}, but the charge failed with this message:", | ||
format_currency(exchange.amount + exchange.fee, 'USD'), | ||
('<b><a href="{0}">{1}</a></b>'|safe).format( | ||
participant.profile_url+'giving/', | ||
top_tippee if ntippees == 1 else ngettext('{0} and {n} other', | ||
'{0} and {n} others', | ||
ntippees - 1, | ||
top_tippee))) }} | ||
|
||
<pre>{{ exchange.note }}</pre> | ||
|
||
<a href="{{ participant.profile_url+'routes/credit-card.html' }}" | ||
style="{{ button_style }}">{{ _("Fix Credit Card") }}</a> | ||
|
||
[---] text/plain | ||
{{ _("We tried to charge your credit card {0} today, to fund your ongoing support for {1}, but the charge failed with this message:", | ||
format_currency(exchange.amount + exchange.fee, 'USD'), | ||
top_tippee if ntippees == 1 else ngettext('{0} and {n} other', | ||
'{0} and {n} others', | ||
ntippees - 1, | ||
top_tippee)) }} | ||
|
||
{{ exchange.note }} | ||
|
||
{{ _("Follow this link to fix your credit card:") }} {{ participant.profile_url+'routes/credit-card.html' }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{{ _("Thanks for supporting {0}!", top_tippee) }} | ||
|
||
[---] text/html | ||
{{ _("We charged your credit card {0} today, to fund your ongoing support for {1}. Thanks for using Gratipay!", | ||
format_currency(exchange.amount + exchange.fee, 'USD'), | ||
('<b><a href="{0}">{1}</a></b>'|safe).format( | ||
participant.profile_url+'giving/', | ||
top_tippee if ntippees == 1 else ngettext('{0} and {n} other', | ||
'{0} and {n} others', | ||
ntippees - 1, | ||
top_tippee))) }} | ||
<br> | ||
<br> | ||
<a href="{{ '{}receipts/{}.html'.format(participant.profile_url, exchange.id) }}" | ||
style="{{ button_style }}">{{ _("View Receipt") }}</a> | ||
|
||
[---] text/plain | ||
{{ _("We charged your credit card {0} today, to fund your ongoing support for {1}. Thanks for using Gratipay!", | ||
format_currency(exchange.amount + exchange.fee, 'USD'), | ||
top_tippee if ntippees == 1 else ngettext('{0} and {n} other', | ||
'{0} and {n} others', | ||
ntippees - 1, | ||
top_tippee)) }} | ||
|
||
{{ _("Follow this link to view your receipt:") }} {{ '{}receipts/{}.html'.format(participant.profile_url, exchange.id) }} | ||
|
||
{{ _("Follow this link if you want to view or modify your payments:") }} {{ participant.profile_url+'giving/' }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
BEGIN; | ||
ALTER TABLE participants ADD COLUMN notify_charge int DEFAULT 3; | ||
ALTER TABLE participants | ||
ALTER COLUMN notify_on_opt_in DROP DEFAULT, | ||
ALTER COLUMN notify_on_opt_in TYPE int USING notify_on_opt_in::int, | ||
ALTER COLUMN notify_on_opt_in SET DEFAULT 1; | ||
END; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
from gratipay.models.participant import Participant | ||
from gratipay.testing import Foobar, Harness | ||
from gratipay.testing.balanced import BalancedHarness | ||
from gratipay.testing.emails import EmailHarness | ||
|
||
|
||
class TestPayday(BalancedHarness): | ||
|
@@ -245,13 +246,11 @@ def test_end_raises_NoPayday(self): | |
|
||
@mock.patch('gratipay.billing.payday.log') | ||
@mock.patch('gratipay.billing.payday.Payday.payin') | ||
@mock.patch('gratipay.billing.payday.Payday.end') | ||
def test_payday(self, end, payin, log): | ||
def test_payday(self, payin, log): | ||
greeting = 'Greetings, program! It\'s PAYDAY!!!!' | ||
Payday.start().run() | ||
log.assert_any_call(greeting) | ||
assert payin.call_count == 1 | ||
assert end.call_count == 1 | ||
|
||
|
||
class TestPayin(BalancedHarness): | ||
|
@@ -529,3 +528,24 @@ def test_payout_ach_error(self, ach_credit): | |
Payday.start().payout() | ||
payday = self.fetch_payday() | ||
assert payday['nach_failing'] == 1 | ||
|
||
|
||
class TestNotifyParticipants(EmailHarness): | ||
|
||
def test_it_notifies_participants(self): | ||
kalel = self.make_participant('kalel', claimed_time='now', is_suspicious=False, | ||
email_address='[email protected]', notify_charge=3) | ||
lily = self.make_participant('lily', claimed_time='now', is_suspicious=False) | ||
kalel.set_tip_to(lily, 10) | ||
|
||
for status in ('failed', 'succeeded'): | ||
payday = Payday.start() | ||
self.make_exchange('balanced-cc', 10, 0, kalel, status) | ||
payday.end() | ||
payday.notify_participants() | ||
|
||
emails = self.db.one('SELECT * FROM email_queue') | ||
assert emails.spt_name == 'charge_'+status | ||
|
||
Participant.dequeue_emails() | ||
assert self.get_last_email()['to'][0]['email'] == '[email protected]' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,7 +49,7 @@ def test_take_over_sends_notifications_to_patrons(self): | |
|
||
def test_opt_in_notification_includes_unsubscribe(self): | ||
carl_twitter = self.make_elsewhere('twitter', 1, 'carl') | ||
roy = self.make_participant('roy', claimed_time='now', email_address='[email protected]', notify_on_opt_in=True) | ||
roy = self.make_participant('roy', claimed_time='now', email_address='[email protected]', notify_on_opt_in=1) | ||
roy.set_tip_to(carl_twitter.participant.username, '100') | ||
|
||
AccountElsewhere.from_user_name('twitter', 'carl').opt_in('carl') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this code difficult to read. You mentioned (IRC) wanting to refactor how we're doing notifications. Does this point us in that direction? Are you thinking we'll fold all notifications together into one column that we'll work with via bitmasks? Are you expecting that we'll use bitwise operators with ints? I'd find it easier to comprehend bitwise code if it used
0b00
(Python) andB'00'
(Postgres). It'd be even easier if we used constants (e.g.,NOTIFY_CHARGE_FAILURE
).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
No, but that may be a better idea than what I had in mind, I'll see if it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Changaco Can we please not use ints for bitmasks? Too clever for me, sorry. :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on that. Either don't use them at all, or use abstraction so that we don't have to work with bits directly.