Skip to content

Commit

Permalink
Created subscription accordingly to payment
Browse files Browse the repository at this point in the history
close #3763
  • Loading branch information
renzon committed Jun 5, 2021
1 parent 989c47a commit 0c8fd1a
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 7 deletions.
2 changes: 2 additions & 0 deletions pythonpro/domain/checkout_domain.py
Expand Up @@ -6,6 +6,7 @@
from pythonpro.domain import user_domain
from pythonpro.domain.hotzapp_domain import verify_purchase, send_purchase_notification
from pythonpro.email_marketing import facade as email_marketing_facade
from pythonpro.memberkit import facade as memberkit_facade

__all__ = ['contact_info_listener', 'user_factory', 'payment_handler_task', 'payment_change_handler']

Expand Down Expand Up @@ -56,6 +57,7 @@ def payment_handler_task(payment_id):
else:
status = payment.status()
if status == django_pagarme_facade.PAID:
memberkit_facade.create_new_subscription(payment, 'Criação como resposta de pagamento no Pagarme')
user = payment.user
if payment.payment_method == django_pagarme_facade.BOLETO:
email_marketing_facade.remove_tags.delay(user.email, user.id, f'{slug}-boleto', f'{slug}-refused')
Expand Down
24 changes: 24 additions & 0 deletions pythonpro/domain/tests/test_checkout/test_payment_handler.py
Expand Up @@ -4,6 +4,7 @@
from model_bakery import baker

from pythonpro.domain import checkout_domain
from pythonpro.memberkit.models import SubscriptionType, Subscription, PaymentItemConfigToSubscriptionType


@pytest.fixture
Expand Down Expand Up @@ -31,6 +32,9 @@ def test_pagarme_payment_paid_boleto(db, tag_as_mock, remove_tags_mock, promote_
payment = baker.make(PagarmePayment, payment_method=facade.BOLETO, user=logged_user)
baker.make(PagarmeNotification, status=facade.PAID, payment=payment)
config = baker.make(PagarmeItemConfig, payments=[payment])
subscription_type = baker.make(SubscriptionType)
PaymentItemConfigToSubscriptionType.objects.create(payment_item=config, subscription_type=subscription_type)

checkout_domain.payment_handler_task(payment.id)
assert tag_as_mock.called is False
remove_tags_mock.assert_called_once_with(
Expand All @@ -40,11 +44,31 @@ def test_pagarme_payment_paid_boleto(db, tag_as_mock, remove_tags_mock, promote_
send_purchase_notification_mock.asser_called_once_with(payment.id)


def test_subscription_creation(db, tag_as_mock, remove_tags_mock, promote_user_mock, logged_user,
send_purchase_notification_mock):
payment = baker.make(PagarmePayment, payment_method=facade.BOLETO, user=logged_user)
baker.make(PagarmeNotification, status=facade.PAID, payment=payment)
config = baker.make(PagarmeItemConfig, payments=[payment])
subscription_type = baker.make(SubscriptionType)
PaymentItemConfigToSubscriptionType.objects.create(payment_item=config, subscription_type=subscription_type)
checkout_domain.payment_handler_task(payment.id)
subscription = Subscription.objects.first()
assert subscription is not None
assert subscription.subscriber_id == payment.user_id
assert subscription.status == Subscription.Status.INACTIVE
assert subscription.payment_id == payment.id
assert list(subscription.subscription_types.all()) == [subscription_type]
assert subscription.responsible is None
assert subscription.observation == 'Criação como resposta de pagamento no Pagarme'


def test_pagarme_payment_paid_credit_card(db, tag_as_mock, remove_tags_mock, promote_user_mock, logged_user,
send_purchase_notification_mock):
payment = baker.make(PagarmePayment, payment_method=facade.CREDIT_CARD, user=logged_user)
baker.make(PagarmeNotification, status=facade.PAID, payment=payment)
config = baker.make(PagarmeItemConfig, payments=[payment])
subscription_type = baker.make(SubscriptionType)
PaymentItemConfigToSubscriptionType.objects.create(payment_item=config, subscription_type=subscription_type)
checkout_domain.payment_handler_task(payment.id)
assert tag_as_mock.called is False
remove_tags_mock.assert_called_once_with(
Expand Down
14 changes: 13 additions & 1 deletion pythonpro/memberkit/admin.py
Expand Up @@ -6,7 +6,7 @@

# Register your models here.
from pythonpro.memberkit import facade
from pythonpro.memberkit.models import SubscriptionType, PaymentItemConfigToSubscriptionType
from pythonpro.memberkit.models import SubscriptionType, PaymentItemConfigToSubscriptionType, Subscription


class PaymentItemConfigInline(admin.TabularInline):
Expand Down Expand Up @@ -45,3 +45,15 @@ def has_delete_permission(self, request, obj=None):
@admin.register(PagarmeItemConfig)
class NewPagarmeItemConfigAdmin(PagarmeItemConfigAdmin):
inlines = [PaymentItemConfigInline]


@admin.register(Subscription)
class SubscriptionAdmin(admin.ModelAdmin):
fields = ['subscriber', 'subscription_types', 'observation']
list_display = ['subscriber', 'responsible', 'status', 'created_at', 'updated_at']
autocomplete_fields = ['subscriber']
search_fields = ['subscriber__email']
list_filter = ['status', 'subscription_types']

def has_delete_permission(self, request, obj=None):
return False
17 changes: 16 additions & 1 deletion pythonpro/memberkit/facade.py
@@ -1,11 +1,26 @@
from typing import List

from pythonpro.memberkit import api
from pythonpro.memberkit.models import SubscriptionType
from pythonpro.memberkit.models import SubscriptionType, Subscription


def synchronize_subscription_types() -> List[SubscriptionType]:
return [
SubscriptionType.objects.update_or_create(id=dct['id'], name=dct['name'])[0]
for dct in api.list_membership_levels()
]


def create_new_subscription(payment: 'django_pagarme.models.PagarmePayment', observation: str = '') -> Subscription:
subscription_types = [item.subscription_type_relation.subscription_type for item in payment.items.all()]
if len(subscription_types) == 0:
raise ValueError(f"Payment {payment} doesn't have subscription types")

subscription = Subscription.objects.create(
status=Subscription.Status.INACTIVE,
payment=payment,
subscriber=payment.user,
observation=observation
)
subscription.subscription_types.set(subscription_types)
return subscription
35 changes: 35 additions & 0 deletions pythonpro/memberkit/migrations/0003_subscription.py
@@ -0,0 +1,35 @@
# Generated by Django 3.2.4 on 2021-06-05 20:15

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('django_pagarme', '0004_pagarme_item_config_available_until'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('memberkit', '0002_create_relationship_with_payment_config_item'),
]

operations = [
migrations.CreateModel(
name='Subscription',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('A', 'Ativo'), ('I', 'Inativo')], max_length=1)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('observation', models.TextField(blank=True, default='', verbose_name='Observação')),
('payment', models.OneToOneField(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='django_pagarme.pagarmepayment')),
('responsible', models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_subscriptions', to=settings.AUTH_USER_MODEL)),
('subscriber', models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='subscriptions', to=settings.AUTH_USER_MODEL)),
('subscription_types', models.ManyToManyField(related_name='subscriptions', to='memberkit.SubscriptionType')),
],
options={
'verbose_name': 'Assinatura',
'verbose_name_plural': 'Assinaturas',
},
),
]
26 changes: 21 additions & 5 deletions pythonpro/memberkit/models.py
@@ -1,3 +1,4 @@
from django.contrib.auth import get_user_model
from django.db import models


Expand All @@ -22,8 +23,23 @@ class PaymentItemConfigToSubscriptionType(models.Model):
def __str__(self):
return f'{self.payment_item} -> {self.subscription_type}'

# class Subscription(models.Model):
# created_at = models.DateTimeField(auto_now_add=True)
# updated_at = models.DateTimeField(auto_now_add=True)
# payment = models.OneToOneField('PagarmePayment', on_delete=models.DO_NOTHING, )
# subscription_type = models.OneToOneField(SubscriptionType, null=False, on_delete=models.DO_NOTHING)

class Subscription(models.Model):
class Meta:
verbose_name = 'Assinatura'
verbose_name_plural = 'Assinaturas'

class Status(models.TextChoices):
ACTIVE = 'A', 'Ativo'
INACTIVE = 'I', 'Inativo'

status = models.CharField(max_length=1, choices=Status.choices)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
payment = models.OneToOneField('django_pagarme.PagarmePayment', on_delete=models.DO_NOTHING, null=True)
subscription_types = models.ManyToManyField(SubscriptionType, related_name='subscriptions')
subscriber = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING, null=True,
related_name='subscriptions')
responsible = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING, null=True,
related_name='created_subscriptions')
observation = models.TextField(verbose_name='Observação', blank=True, default='')

0 comments on commit 0c8fd1a

Please sign in to comment.