Skip to content

Commit 58c4d43

Browse files
renzonrenzon
authored andcommitted
Created templates JRPV lista vip
Added logic for expiring licenses close #4058 Fixed lista de espera page
1 parent 4fda9da commit 58c4d43

File tree

7 files changed

+156
-6
lines changed

7 files changed

+156
-6
lines changed

pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote3_lista_de_espera.html renamed to pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lista_de_espera.html

File renamed without changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% extends 'django_pagarme/pagarme.html' %}
2+
{% block sidebar %}
3+
<div class="sidebar-item">
4+
<h4 class="white-txt">Revisar Lista VIP</h4>
5+
<div>Online para tirar TODAS suas dúvidas</div>
6+
</div>
7+
8+
{% endblock sidebar %}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{% extends 'core/base_without_nav.html' %}
2+
{% load django_pagarme %}
3+
{% load static %}
4+
{% block title %}Obrigado por se matricular no {{ payment_item_config.name }}{% endblock %}
5+
{% block styles %}{% endblock %}
6+
{% block body_class %}clean-body{% endblock %}
7+
{% block scripts %}{% endblock scripts %}
8+
{% block head %}
9+
<meta content="Agora que você já é um programador profissional, com certeza vão surgir novos desafios. Serão problemas mais complexos, que vão exigir de você novas fontes de conhecimento."
10+
name="description">
11+
<meta content="Oportunidade Única Python Pro!" property="og:title">
12+
<meta content="Agora que você já é um programador profissional, com certeza vão surgir novos desafios. Serão problemas mais complexos, que vão exigir de você novas fontes de conhecimento."
13+
property="og:description">
14+
<meta content="Oportunidade Única Python Pro!" property="twitter:title">
15+
<meta content="Agora que você já é um programador profissional, com certeza vão surgir novos desafios. Serão problemas mais complexos, que vão exigir de você novas fontes de conhecimento."
16+
property="twitter:description">
17+
<meta property="og:type" content="website">
18+
<meta content="summary_large_image" name="twitter:card">
19+
<meta content="width=device-width, initial-scale=1" name="viewport">
20+
<meta content="Webflow" name="generator">
21+
<link href="{% static 'thanks/css/normalize.css' %}" rel="stylesheet" type="text/css">
22+
<link href="{% static 'thanks/css/webflow.css' %}" rel="stylesheet" type="text/css">
23+
<link href="{% static 'thanks/css/python-pro.webflow.css' %}" rel="stylesheet" type="text/css">
24+
<script src="//ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script>
25+
<script type="text/javascript">
26+
WebFont.load({
27+
google: {
28+
families: ["Poppins:regular,500,600,700,800,900"]
29+
}
30+
});
31+
</script>
32+
<!-- [if lt IE 9]>
33+
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"
34+
type="text/javascript"></script><![endif] -->
35+
<script type="text/javascript">
36+
!function (o, c) {
37+
var n = c.documentElement,
38+
t = " w-mod-";
39+
n.className += t + "js", ("ontouchstart" in o || o.DocumentTouch && c instanceof DocumentTouch) && (n.className += t + "touch")
40+
}(window, document);
41+
</script>
42+
<link href="{% static 'thanks/images/webclip.png' %}" rel="apple-touch-icon">
43+
{% endblock head %}
44+
{% block body %}
45+
<div class="header blue">
46+
<div class="header-section">
47+
<div class="header-container">
48+
<div id="w-node-6ab841cb6b5f-dd0aa7ab" class="headline-container centered">
49+
<div class="auto-headline">
50+
<h1 class="dumbo-heading">{% block page_main_title %}Parabéns por se registrar no
51+
{{ payment_item_config.name }}!{% endblock page_main_title %}</h1>
52+
<div class="dumbo-description">Rever copy da lista vip</div>
53+
<img src="{% static 'thanks/images/down-arrow.svg' %}"
54+
data-w-id="32f53c33-6610-0d97-9540-539ac6e9b39f"
55+
style="-webkit-transform:translate3d(0, 0PX, 0) scale3d(1, 1, 1) rotateX(0) rotateY(0) rotateZ(0) skew(0, 0);-moz-transform:translate3d(0, 0PX, 0) scale3d(1, 1, 1) rotateX(0) rotateY(0) rotateZ(0) skew(0, 0);-ms-transform:translate3d(0, 0PX, 0) scale3d(1, 1, 1) rotateX(0) rotateY(0) rotateZ(0) skew(0, 0);transform:translate3d(0, 0PX, 0) scale3d(1, 1, 1) rotateX(0) rotateY(0) rotateZ(0) skew(0, 0)"
56+
alt="" class="image-4"></div>
57+
</div>
58+
</div>
59+
</div>
60+
</div>
61+
<div class="content custom-bg">
62+
<div class="overlap-container">
63+
<div class="video-container">
64+
{% with thanks_video_id='bexSB6jw2m8' %}
65+
{% block thanks_video %}
66+
<div style="padding-top:56.17021276595745%" class="video w-video w-embed">
67+
<iframe class="embedly-embed"
68+
src="//cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F{{ thanks_video_id }}%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D{{ thanks_video_id }}&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F{{ thanks_video_id }}%2Fhqdefault.jpg&key=96f1f04c5f4143bcb0f2e68c87d65feb&type=text%2Fhtml&schema=youtube"
69+
scrolling="no" title="YouTube embed" frameborder="0" allow="autoplay; fullscreen"
70+
allowfullscreen="true"></iframe>
71+
</div>
72+
{% endblock thanks_video %}
73+
{% endwith %}
74+
</div>
75+
</div>
76+
</div>
77+
78+
<div class="content custom-bg bg-v2">
79+
<div class="container">
80+
{% block upsell %}
81+
<div id="w-node-b11fafc8de25-dd0aa7ab" class="container-content">
82+
<h3><a class="btn btn-success" href="{% url 'modules:detail' slug='python-birds' %}">Acessar
83+
Primeiro Curso &raquo;</a></h3>
84+
</div>
85+
{% endblock upsell %}
86+
<div id="w-node-2878d38ff948-dd0aa7ab" class="container-content">
87+
<div class="credits">2020 Python Pro. Todos os direitos reservados.<br>CNPJ: 31.080.715/0001-25<br>+55
88+
12 99141-5422 - suporte@python.pro.br
89+
</div>
90+
</div>
91+
</div>
92+
</div>
93+
<script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.4.1.min.220afd743d.js?site=5f07a1c9ac6e0b5937b108a7"
94+
type="text/javascript" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
95+
crossorigin="anonymous"></script>
96+
<script src="{% static 'thanks/js/webflow.js' %}" type="text/javascript"></script>
97+
{% include 'core/_scripts.html' %}
98+
<!-- [if lte IE 9]>
99+
<script src="//cdnjs.cloudflare.com/ajax/libs/placeholders/3.0.2/placeholders.min.js"></script><![endif] -->
100+
{% endblock body %}
101+
{% block footer %}{% endblock footer %}

pythonpro/memberkit/admin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class PaymentItemConfigInline(admin.TabularInline):
2121
@admin.register(SubscriptionType)
2222
class SubscriptionTypeAdmin(admin.ModelAdmin):
2323
change_list_template = 'memberkit/subscriptiontype/synchronize_button.html'
24-
fields = ['id', 'name', 'email_marketing_tags', 'discourse_groups', 'include_on_cohort']
24+
fields = ['id', 'name', 'email_marketing_tags', 'discourse_groups', 'include_on_cohort', 'days_of_access']
2525
list_display = fields
2626
readonly_fields = ['id', 'name']
2727
inlines = [PaymentItemConfigInline]
@@ -68,10 +68,10 @@ def queryset(self, request, queryset):
6868

6969
@admin.register(Subscription)
7070
class SubscriptionAdmin(admin.ModelAdmin):
71-
fields = ['payment', 'subscriber', 'subscription_types', 'observation']
71+
fields = ['payment', 'subscriber', 'subscription_types', 'observation', 'days_of_access']
7272
list_display = [
7373
'id', 'subscriber', 'pagarme_url_field', 'memberkit_user_url_field', 'responsible', 'status',
74-
'created_at', 'updated_at', 'activated_at'
74+
'created_at', 'updated_at', 'activated_at', 'expires_at'
7575
]
7676
autocomplete_fields = ['subscriber']
7777
search_fields = ['subscriber__email', 'payment__transaction_id']

pythonpro/memberkit/facade.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from builtins import Exception
2+
from datetime import timedelta
23
from typing import List
34

45
from django.utils import timezone
@@ -22,29 +23,35 @@ def create_new_subscription(payment, observation: str = '') -> Subscription:
2223
if len(subscription_types) == 0:
2324
raise ValueError(f"Payment {payment} doesn't have subscription types")
2425

26+
# For now subscriptions has only one subscription type, so it's assumed to take
27+
# days of access from the first one
28+
days_of_access = subscription_types[0].days_of_access
29+
2530
subscription = Subscription.objects.create(
2631
status=Subscription.Status.INACTIVE,
2732
payment=payment,
2833
subscriber=payment.user,
29-
observation=observation
34+
observation=observation,
35+
days_of_access=days_of_access
3036
)
3137
subscription.subscription_types.set(subscription_types)
3238
return subscription
3339

3440

3541
def activate(subscription, responsible=None, observation=''):
3642
user = subscription.subscriber
43+
subscription.activated_at = timezone.now()
3744
for subscription_type in subscription.subscription_types.all():
45+
expires_at = subscription.activated_at + timedelta(days=subscription_type.days_of_access)
3846
response_json = api.activate_user(
39-
user.get_full_name(), user.email, subscription_type.id
47+
user.get_full_name(), user.email, subscription_type.id, expires_at
4048
)
4149
subscription.memberkit_user_id = response_json['id']
4250
subscription.status = Subscription.Status.ACTIVE
4351
if subscription.observation:
4452
subscription.observation += f'\n\n {observation}'
4553
else:
4654
subscription.observation = observation
47-
subscription.activated_at = timezone.now()
4855
if responsible:
4956
subscription.responsible = responsible
5057
subscription.save()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 3.2.7 on 2021-09-15 01:24
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
('memberkit', '0007_allow_subscripiton_be_saved_without_payment'),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name='subscription',
14+
name='days_of_access',
15+
field=models.IntegerField(default=73000),
16+
),
17+
migrations.AddField(
18+
model_name='subscriptiontype',
19+
name='days_of_access',
20+
field=models.IntegerField(default=73000),
21+
),
22+
]

pythonpro/memberkit/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
from datetime import timedelta
2+
13
from django.contrib.auth import get_user_model
24
from django.contrib.postgres.fields import ArrayField
35
from django.db import models
46

7+
_ETERNAL_IN_HUMAM_LIFE_DAYS = 365 * 200
8+
59

610
class SubscriptionType(models.Model):
711
id = models.IntegerField(unique=True, primary_key=True)
812
name = models.CharField(max_length=128)
913
email_marketing_tags = ArrayField(models.CharField(max_length=64), default=list)
1014
discourse_groups = ArrayField(models.CharField(max_length=64), default=list)
1115
include_on_cohort = models.BooleanField(default=False, verbose_name='Incluir na última turma')
16+
days_of_access = models.IntegerField(default=_ETERNAL_IN_HUMAM_LIFE_DAYS)
1217

1318
def __str__(self):
1419
return f'Assinatura: {self.name}'
@@ -40,6 +45,7 @@ class Status(models.TextChoices):
4045
status = models.CharField(max_length=1, choices=Status.choices)
4146
created_at = models.DateTimeField(auto_now_add=True)
4247
updated_at = models.DateTimeField(auto_now=True)
48+
days_of_access = models.IntegerField(default=_ETERNAL_IN_HUMAM_LIFE_DAYS)
4349
payment = models.OneToOneField('django_pagarme.PagarmePayment', on_delete=models.DO_NOTHING, null=True, blank=True)
4450
subscription_types = models.ManyToManyField(SubscriptionType, related_name='subscriptions')
4551
subscriber = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING, null=True,
@@ -54,6 +60,12 @@ class Status(models.TextChoices):
5460
def include_on_cohort(self):
5561
return self.subscription_types.filter(include_on_cohort=True).exists()
5662

63+
@property
64+
def expires_at(self):
65+
if self.activated_at:
66+
return self.activated_at + timedelta(days=self.days_of_access)
67+
return '--'
68+
5769
@property
5870
def email_marketing_tags(self):
5971
tags = []

0 commit comments

Comments
 (0)