diff --git a/.gitignore b/.gitignore
index d9dc4c9..09f5125 100644
--- a/.gitignore
+++ b/.gitignore
@@ -198,4 +198,3 @@ target/
*.css.map
################################################################################
-
diff --git a/conf/deploy/common.py b/conf/deploy/common.py
new file mode 100644
index 0000000..7a4f9d3
--- /dev/null
+++ b/conf/deploy/common.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+PROJECT_NAME = 'dokumentor'
+REPO = 'git@bitbucket.org:Air51/dokumentor_dev.git'
+BRANCH = 'develop'
diff --git a/conf/deploy/stage.py b/conf/deploy/stage.py
new file mode 100644
index 0000000..525ba05
--- /dev/null
+++ b/conf/deploy/stage.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+USER = 'mitri4'
+PASS = '9091324913Dasha'
+HOSTS = ['mitri4.pro:8022']
diff --git a/conf/deploy/stage.py.example b/conf/deploy/stage.py.example
new file mode 100644
index 0000000..8475f7e
--- /dev/null
+++ b/conf/deploy/stage.py.example
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+from deploy.common import * # noqa
+
+USER = 'username'
+PASS = 'password'
+HOSTS = ['domain_name:ssh_port']
+
diff --git a/requirements/base.txt b/requirements/base.txt
index 6e5f278..4859749 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -71,16 +71,4 @@ django-redis==4.8.0
redis==2.10.5
trans==2.1.0
python-decouple==3.0
-flake8==3.3.0
numpy==1.13.0
-mock==2.0.0
-mockredispy==2.9.3
-pytest-django==3.1.2
-pytest-sugar==0.8.0
-factory-boy==2.8.1
-django-test-plus==1.0.17
-Faker==0.7.15
-coverage==4.4.1
-pytest-flake8==0.8.1
-pycodestyle==2.3.1
-pyflakes==1.5.0
diff --git a/requirements/test.txt b/requirements/test.txt
new file mode 100644
index 0000000..0247a4d
--- /dev/null
+++ b/requirements/test.txt
@@ -0,0 +1,14 @@
+-r base.txt
+freezegun-0.3.9
+mock==2.0.0
+mockredispy==2.9.3
+pytest-django==3.1.2
+pytest-sugar==0.8.0
+factory-boy==2.8.1
+django-test-plus==1.0.17
+Faker==0.7.15
+coverage==4.4.1
+pytest-flake8==0.8.1
+pycodestyle==2.3.1
+pyflakes==1.5.0
+flake8==3.3.0
diff --git a/src/customer/context_processors.py b/src/customer/context_processors.py
index 3571e54..d0f2a13 100644
--- a/src/customer/context_processors.py
+++ b/src/customer/context_processors.py
@@ -3,6 +3,7 @@ import logging
from datetime import datetime, timedelta
from django.core.cache import cache
from customer.models import License
+from customer.utils import get_display_message_for_bonus
log = logging.getLogger(__name__)
@@ -14,11 +15,6 @@ def license_check_soon_ends(request):
days_left = cache.get(f'days_left_{request.user.username}', None)
cur_license = cache.get(f'cur_license_{request.user.username}', None)
- print(license_cookie)
- print(license_15days)
- print(days_left)
- print(cur_license)
-
if not days_left or not cur_license:
now = datetime.today()
cur_license = License.objects.filter(
@@ -66,10 +62,22 @@ def license_check_soon_ends(request):
def confirm_user_bonus(request):
if request.user:
- bonus_url = '#'
- message = f'У вас есть ещё 10 дней, чтобы получить бонус'
- test_message = 'This message is personal confirm for current user'
- return {
- 'confirm_bonus': True,
- 'message_bonus': message
- }
+ context = {}
+ close_bonus_cookie = request.COOKIES.get('close_message_bonus')
+ confirm_bonus_days = cache.get(f'confirm_bonus_days_{request.user.username}', None)
+
+ if confirm_bonus_days >= 0:
+ message = get_display_message_for_bonus(confirm_bonus_days)
+ context['confirm_bonus'] = True
+ context['message'] = message
+ return context
+
+ if not close_bonus_cookie:
+ pass
+ else:
+ return context
+
+ # return {
+ # 'confirm_bonus': True,
+ # 'message_bonus': message
+ # }
diff --git a/src/customer/utils.py b/src/customer/utils.py
index 38df52a..af8a59b 100644
--- a/src/customer/utils.py
+++ b/src/customer/utils.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
+from pytils import numeral
+from django.utils import timezone
from django.conf import settings
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
@@ -9,11 +11,10 @@ from commons.utils import get_site_url
def check_one_profile(profile, now, manual=False):
-
from customer.models import License
profile_is_active = profile.active
- licenses = License.objects.\
+ licenses = License.objects. \
filter(company=profile, date_from__lte=now, date_to__gte=now,
status__in=[-1, 1, 2], deleted=False)
licenses.filter(status=1).update(status=2)
@@ -98,3 +99,58 @@ def raise_if_no_profile(request):
raise Exception(
f"Profile not found for user: {request.user.pk}, '{request.user.username}'"
)
+
+
+def check_confirm_bonus_to_user(user):
+ """
+ Check user for displaying a message with an offer for
+ purchase of licenses for additional bonus licenses
+ Show message only for new users in the period
+ from 5 to 15 day
+ If user already have licenses don't display message
+ :param user: DockUser instance
+ :return: count of days remaining for getting bonus,
+ integer or False if nothing to use
+ """
+ from customer.models import License
+
+ lic = License.objects.filter(
+ company=user.profile,
+ status__in=[1, 2],
+ deleted=False
+ )
+ if lic:
+ return False
+
+ today = timezone.now().date()
+ date_join_start = today - timezone.timedelta(days=15)
+ date_join_end = today - timezone.timedelta(days=6)
+ if date_join_start <= user.date_joined.date() <= date_join_end:
+ delta = user.date_joined.date() - date_join_start
+ return delta.days
+
+ return False
+
+
+def get_display_message_for_bonus(day_count):
+ """
+ Get text to display the message depending on count of days
+ :param day_count: Count of days, integer
+ :return: Message for display in page, string
+ """
+ message = ''
+
+ if type(day_count) == str:
+ return message
+
+ if day_count > 10:
+ return message
+
+ if day_count == 0:
+ message = f'Сегодня последний день что бы получить бонус'
+ if day_count > 0:
+ message = f'У вас есть ещё {day_count} ' \
+ f'{numeral.choose_plural(day_count, "день, дня, дней")}, ' \
+ f'чтобы получить бонус'
+
+ return message
diff --git a/src/factories/models.py b/src/factories/models.py
index 65cf958..780e627 100755
--- a/src/factories/models.py
+++ b/src/factories/models.py
@@ -6,7 +6,7 @@ import factory.fuzzy
from django.contrib.auth import get_user_model
from myauth.models import ConfirmEmail
-from customer.models import UserProfile
+from customer.models import UserProfile, License
from functools import partial
USER_PASSWORD = 'test'
@@ -74,3 +74,35 @@ class ConfirmEmailFactory(factory.django.DjangoModelFactory):
class Meta:
model = ConfirmEmail
+
+
+class LicenseFactory(factory.django.DjangoModelFactory):
+ company = factory.SubFactory(ProfileFactory)
+ term = factory.Iterator([1, 6, 12, 24])
+ date_from = Faker(
+ 'past_datetime',
+ start_date='-30d',
+ tzinfo=pytz.UTC
+ )
+ date_to = Faker(
+ 'future_datetime',
+ end_date='+30d',
+ tzinfo=pytz.UTC
+ )
+ payform = factory.Iterator([0, 1])
+ status = factory.Iterator([1, 2])
+ order_date = Faker(
+ 'past_datetime',
+ start_date='-30d',
+ tzinfo=pytz.UTC
+ )
+ paid_date = Faker(
+ 'past_datetime',
+ start_date='-30d',
+ tzinfo=pytz.UTC
+ )
+ pay_sum = factory.Iterator([1000, 2000])
+ deleted = False
+
+ class Meta:
+ model = License
diff --git a/src/tests/fixtures/models.py b/src/tests/fixtures/models.py
index 0bc2e7d..7f88d35 100644
--- a/src/tests/fixtures/models.py
+++ b/src/tests/fixtures/models.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
import pytest
-from factories.models import UserFactory, ConfirmEmailFactory
+from factories.models import UserFactory, ConfirmEmailFactory, LicenseFactory
@pytest.fixture
@@ -17,3 +17,12 @@ def confirm_email():
def profile():
_user = UserFactory()
return _user.profile
+
+
+@pytest.fixture()
+def lic():
+ _user = UserFactory()
+ _lic = LicenseFactory()
+ _lic.company = _user.profile
+ _lic.save()
+ return _lic
diff --git a/src/tests/test_tasks.py b/src/tests/test_tasks.py
index 0ea226b..6fb5417 100644
--- a/src/tests/test_tasks.py
+++ b/src/tests/test_tasks.py
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
import pytest
+from freezegun import freeze_time
+
from django.utils import timezone
+
from myauth.models import DokUser, ConfirmEmail
from customer.models import UserProfile
@@ -23,6 +26,7 @@ dates_lt_five = [timezone.now() - timezone.timedelta(days=5),
dates_bonus = [timezone.now() - timezone.timedelta(days=5)]
+@freeze_time("2017-06-28 00:21:34", tz_offset=2)
@pytest.mark.parametrize('create_date', dates_gte_five)
@pytest.mark.django_db
def test_delete_not_activated_users_great_five_days(user, create_date):
@@ -61,6 +65,7 @@ def test_delete_not_activated_users_less_five_day(user, create_date):
assert ConfirmEmail.objects.count() == 1
+@freeze_time("2017-06-28 00:21:34", tz_offset=2)
@pytest.mark.parametrize('create_date', dates_bonus)
@pytest.mark.django_db
def test_send_offer_for_get_bonus(user, create_date):
diff --git a/src/tests/test_utils.py b/src/tests/test_utils.py
index 35be02c..d3a651b 100644
--- a/src/tests/test_utils.py
+++ b/src/tests/test_utils.py
@@ -4,7 +4,19 @@ import pytest
from django.utils import timezone
from commons.utils import get_site_url
-from customer.utils import check_one_profile
+from customer.utils import check_one_profile, check_confirm_bonus_to_user
+from customer.utils import get_display_message_for_bonus
+
+
+dates = [timezone.now() - timezone.timedelta(days=6),
+ timezone.now() - timezone.timedelta(days=10),
+ timezone.now() - timezone.timedelta(days=15)]
+
+dates_not_in_range = [timezone.now() - timezone.timedelta(days=5),
+ timezone.now() - timezone.timedelta(days=16)]
+
+days = [1, 5, 10, 4, 6, 0]
+not_days = ['1', 11, 'test']
def test_utils_with_request(mocked_request):
@@ -17,6 +29,50 @@ def test_utils_without_request():
assert len(url.split('//')) == 2
+@pytest.mark.parametrize('create_date', dates)
+@pytest.mark.django_db
+def test_check_confirm_bonus_to_user(user, create_date):
+ user.date_joined = create_date
+ user.save()
+ day_remain = check_confirm_bonus_to_user(user)
+ assert day_remain >= 0
+
+
+@pytest.mark.parametrize('create_date', dates_not_in_range)
+@pytest.mark.django_db
+def test_check_confirm_bonus_to_user_not_in_range(user, create_date):
+ user.date_joined = create_date
+ user.save()
+ day_remain = check_confirm_bonus_to_user(user)
+ assert day_remain is False
+
+
+@pytest.mark.parametrize('create_date', dates)
+@pytest.mark.django_db
+def test_check_confirm_bonus_to_user_with_license(lic, create_date):
+ user = lic.company.users.first()
+ user.date_joined = create_date
+ user.save()
+ day_remain = check_confirm_bonus_to_user(user)
+ assert day_remain is False
+
+
+@pytest.mark.parametrize('count_day', days)
+def test_get_display_message_for_bonus(count_day):
+ text = get_display_message_for_bonus(count_day)
+ assert text != ''
+ if count_day == 0:
+ assert 'последний' in text
+ if count_day != 0:
+ assert 'последний' not in text
+
+
+@pytest.mark.parametrize('count_day', not_days)
+def test_get_display_message_for_bonus_not_valid(count_day):
+ text = get_display_message_for_bonus(count_day)
+ assert text == ''
+
+
@pytest.mark.django_db
def test_check_one_profile(profile):
check_one_profile(profile, timezone.now(), manual=False)