Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pythonpro/core/facade.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import datetime

from rolepermissions.checkers import has_role
from rolepermissions.roles import assign_role, remove_role

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


def find_leads_by_date_joined_interval(begin: datetime, end: datetime):
return list(user for user in User.objects.filter(date_joined__gte=begin, date_joined__lte=end).all() if
not has_role(user, ['client', 'member']))


def find_user_by_email(email: str):
return User.objects.filter(email=email).get()

Expand Down
16 changes: 16 additions & 0 deletions pythonpro/facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from pythonpro.core import facade as _core_facade
from pythonpro.core.models import User as _User
from pythonpro.mailchimp import facade as _mailchimp_facade
from pythonpro.payments import facade as _payments_facade

UserCreationException = _core_facade.UserCreationException # exposing exception on Facade

Expand Down Expand Up @@ -110,3 +111,18 @@ def find_user_by_id(user_id: int) -> _User:
:return:
"""
return _core_facade.find_user_by_id(user_id)


def run_pytools_promotion_campaign() -> int:
"""
Run pytools campaign for users registered 7 weeks ago
:return: number of user's marked for promotion
"""
begin, end = _payments_facade.calculate_7th_week_before_promotion()
promotion_users = _core_facade.find_leads_by_date_joined_interval(begin, end)
for user in promotion_users:
try:
_mailchimp_facade.tag_as(user.email, 'pytools-promotion')
except _MailChimpError:
pass
return len(promotion_users)
11 changes: 10 additions & 1 deletion pythonpro/payments/facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ def is_on_pytools_promotion_season(creation: datetime) -> bool:
:param creation: datetime of creation
:return: boolean indication if its os promotion period or not
"""
creation_begin, creation_end = calculate_7th_week_before_promotion()
return creation_begin <= creation <= creation_end


def calculate_7th_week_before_promotion() -> Tuple[datetime, datetime]:
"""
Calculate 7th week before promotion. Useful to know user created on that period
:return: Tuple where first item is the interval's begin and second is the interval's end
"""
promotion_begin, _ = calculate_pytools_promotion_interval()
creation_begin = promotion_begin + relativedelta(weekday=MO(-8))
creation_end = creation_begin + relativedelta(days=6, hour=23, minute=59, second=59)
return creation_begin <= creation <= creation_end
return creation_begin, creation_end
Empty file.
Empty file.
14 changes: 14 additions & 0 deletions pythonpro/payments/management/commands/pytools_promotion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.core.management import BaseCommand

from pythonpro import facade


class Command(BaseCommand):
help = 'Mark users for pytools 4 day promotion'

def add_arguments(self, parser):
pass

def handle(self, *args, **options):
promotion_users = facade.run_pytools_promotion_campaign()
self.stdout.write(self.style.SUCCESS(f'Successfully marked {promotion_users} users for promotions'))
8 changes: 8 additions & 0 deletions pythonpro/payments/tests/test_pytools_promotion_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.core.management import call_command


def test_pytools_command(mocker):
mock = mocker.patch(
'pythonpro.payments.management.commands.pytools_promotion.facade.run_pytools_promotion_campaign')
call_command('pytools_promotion')
mock.assert_called_once_with()
62 changes: 62 additions & 0 deletions pythonpro/tests/test_pytools_promotion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from datetime import datetime

import pytz
from freezegun import freeze_time
from model_mommy import mommy
from rolepermissions.roles import assign_role

from pythonpro import facade


def test_leads_in_promotion_period(db, django_user_model, mocker):
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
for user in users_created_seven_weeks_ago:
assign_role(user, 'lead')
with freeze_time('2019-07-22'):
assert len(users_created_seven_weeks_ago) == facade.run_pytools_promotion_campaign()
for user in users_created_seven_weeks_ago:
tag_as_mock.assert_any_call(user.email, 'pytools-promotion')


def test_clients_not_marked_in_promotion_period(db, django_user_model, mocker):
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
for user in users_created_seven_weeks_ago:
assign_role(user, 'client')
with freeze_time('2019-07-22'):
assert 0 == facade.run_pytools_promotion_campaign()
assert tag_as_mock.call_count == 0


def test_members_not_marked_in_promotion_period(db, django_user_model, mocker):
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(3, 10))
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
users_created_seven_weeks_ago = [mommy.make(django_user_model, date_joined=d) for d in dts]
for user in users_created_seven_weeks_ago:
assign_role(user, 'client')
with freeze_time('2019-07-22'):
assert 0 == facade.run_pytools_promotion_campaign()
assert tag_as_mock.call_count == 0


def test_before_promotion_period(db, django_user_model, mocker):
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(1, 3))
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
for d in dts:
mommy.make(django_user_model, date_joined=d)
with freeze_time('2019-07-22'):
assert 0 == facade.run_pytools_promotion_campaign()
assert tag_as_mock.call_count == 0


def test_after_promotion_period(db, django_user_model, mocker):
dts = (datetime(2019, 6, day, tzinfo=pytz.utc) for day in range(10, 13))
tag_as_mock = mocker.patch('pythonpro.facade._mailchimp_facade.tag_as')
for d in dts:
mommy.make(django_user_model, date_joined=d)
with freeze_time('2019-07-22'):
assert 0 == facade.run_pytools_promotion_campaign()
assert tag_as_mock.call_count == 0