Skip to content

Commit 4d2e7e8

Browse files
renzonrenzon
authored andcommitted
Implemented user's mark for promotion
close #1346
1 parent 20e3572 commit 4d2e7e8

File tree

8 files changed

+117
-1
lines changed

8 files changed

+117
-1
lines changed

pythonpro/core/facade.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from datetime import datetime
2+
13
from rolepermissions.checkers import has_role
24
from rolepermissions.roles import assign_role, remove_role
35

@@ -79,6 +81,11 @@ def promote_to_client(user: User) -> None:
7981
remove_role(user, 'lead')
8082

8183

84+
def find_leads_by_date_joined_interval(begin: datetime, end: datetime):
85+
return list(user for user in User.objects.filter(date_joined__gte=begin, date_joined__lte=end).all() if
86+
not has_role(user, ['client', 'member']))
87+
88+
8289
def find_user_by_email(email: str):
8390
return User.objects.filter(email=email).get()
8491

pythonpro/facade.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pythonpro.core import facade as _core_facade
1010
from pythonpro.core.models import User as _User
1111
from pythonpro.mailchimp import facade as _mailchimp_facade
12+
from pythonpro.payments import facade as _payments_facade
1213

1314
UserCreationException = _core_facade.UserCreationException # exposing exception on Facade
1415

@@ -110,3 +111,18 @@ def find_user_by_id(user_id: int) -> _User:
110111
:return:
111112
"""
112113
return _core_facade.find_user_by_id(user_id)
114+
115+
116+
def run_pytools_promotion_campaign() -> int:
117+
"""
118+
Run pytools campaign for users registered 7 weeks ago
119+
:return: number of user's marked for promotion
120+
"""
121+
begin, end = _payments_facade.calculate_7th_week_before_promotion()
122+
promotion_users = _core_facade.find_leads_by_date_joined_interval(begin, end)
123+
for user in promotion_users:
124+
try:
125+
_mailchimp_facade.tag_as(user.email, 'pytools-promotion')
126+
except _MailChimpError:
127+
pass
128+
return len(promotion_users)

pythonpro/payments/facade.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,16 @@ def is_on_pytools_promotion_season(creation: datetime) -> bool:
5959
:param creation: datetime of creation
6060
:return: boolean indication if its os promotion period or not
6161
"""
62+
creation_begin, creation_end = calculate_7th_week_before_promotion()
63+
return creation_begin <= creation <= creation_end
64+
65+
66+
def calculate_7th_week_before_promotion() -> Tuple[datetime, datetime]:
67+
"""
68+
Calculate 7th week before promotion. Useful to know user created on that period
69+
:return: Tuple where first item is the interval's begin and second is the interval's end
70+
"""
6271
promotion_begin, _ = calculate_pytools_promotion_interval()
6372
creation_begin = promotion_begin + relativedelta(weekday=MO(-8))
6473
creation_end = creation_begin + relativedelta(days=6, hour=23, minute=59, second=59)
65-
return creation_begin <= creation <= creation_end
74+
return creation_begin, creation_end

pythonpro/payments/management/__init__.py

Whitespace-only changes.

pythonpro/payments/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from django.core.management import BaseCommand
2+
3+
from pythonpro import facade
4+
5+
6+
class Command(BaseCommand):
7+
help = 'Mark users for pytools 4 day promotion'
8+
9+
def add_arguments(self, parser):
10+
pass
11+
12+
def handle(self, *args, **options):
13+
promotion_users = facade.run_pytools_promotion_campaign()
14+
self.stdout.write(self.style.SUCCESS(f'Successfully marked {promotion_users} users for promotions'))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from django.core.management import call_command
2+
3+
4+
def test_pytools_command(mocker):
5+
mock = mocker.patch(
6+
'pythonpro.payments.management.commands.pytools_promotion.facade.run_pytools_promotion_campaign')
7+
call_command('pytools_promotion')
8+
mock.assert_called_once_with()
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from datetime import datetime
2+
3+
import pytz
4+
from freezegun import freeze_time
5+
from model_mommy import mommy
6+
from rolepermissions.roles import assign_role
7+
8+
from pythonpro import facade
9+
10+
11+
def test_leads_in_promotion_period(db, django_user_model, mocker):
12+
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
13+
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
14+
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
15+
for user in users_created_seven_weeks_ago:
16+
assign_role(user, 'lead')
17+
with freeze_time('2019-07-22'):
18+
assert len(users_created_seven_weeks_ago) == facade.run_pytools_promotion_campaign()
19+
for user in users_created_seven_weeks_ago:
20+
tag_as_mock.assert_any_call(user.email, 'pytools-promotion')
21+
22+
23+
def test_clients_not_marked_in_promotion_period(db, django_user_model, mocker):
24+
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
25+
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
26+
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
27+
for user in users_created_seven_weeks_ago:
28+
assign_role(user, 'client')
29+
with freeze_time('2019-07-22'):
30+
assert 0 == facade.run_pytools_promotion_campaign()
31+
assert tag_as_mock.call_count == 0
32+
33+
34+
def test_members_not_marked_in_promotion_period(db, django_user_model, mocker):
35+
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
36+
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
37+
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
38+
for user in users_created_seven_weeks_ago:
39+
assign_role(user, 'client')
40+
with freeze_time('2019-07-22'):
41+
assert 0 == facade.run_pytools_promotion_campaign()
42+
assert tag_as_mock.call_count == 0
43+
44+
45+
def test_before_promotion_period(db, django_user_model, mocker):
46+
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(1, 3))
47+
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
48+
for d in dts:
49+
mommy.make(django_user_model, date_joined=d)
50+
with freeze_time('2019-07-22'):
51+
assert 0 == facade.run_pytools_promotion_campaign()
52+
assert tag_as_mock.call_count == 0
53+
54+
55+
def test_after_promotion_period(db, django_user_model, mocker):
56+
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(10, 13))
57+
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
58+
for d in dts:
59+
mommy.make(django_user_model, date_joined=d)
60+
with freeze_time('2019-07-22'):
61+
assert 0 == facade.run_pytools_promotion_campaign()
62+
assert tag_as_mock.call_count == 0

0 commit comments

Comments
 (0)