Skip to content

Commit be18554

Browse files
renzonrenzon
authored andcommitted
Created command to fiz inactive subscription with paid payment status
close #3770
1 parent 32afb52 commit be18554

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from django.core.management.base import BaseCommand
2+
from django.db.models import OuterRef, Subquery
3+
from django_pagarme import facade as pagarme_facade
4+
from django_pagarme.models import PagarmePayment, PagarmeNotification
5+
6+
from pythonpro.memberkit.models import Subscription
7+
8+
9+
class Command(BaseCommand):
10+
help = 'Ativa assinatura inativas que possuem última notificação de pagamento como paga'
11+
12+
def add_arguments(self, parser):
13+
pass
14+
15+
def handle(self, *args, **options):
16+
last_notification = PagarmeNotification.objects.filter(payment=OuterRef('pk')).order_by('-creation')
17+
qs = PagarmePayment.objects.filter(
18+
notifications__status=pagarme_facade.PAID,
19+
subscription__isnull=False
20+
).only(
21+
'subscription'
22+
).select_related(
23+
'subscription'
24+
).select_related(
25+
'subscription__subscriber'
26+
).filter(
27+
subscription__status=Subscription.Status.INACTIVE
28+
).annotate(
29+
payment_status=Subquery(last_notification.values('status')[:1])
30+
).filter(payment_status=pagarme_facade.PAID)
31+
for payment in qs:
32+
subscription = payment.subscription
33+
self.stdout.write(self.style.SUCCESS(f'Processando {subscription}'))
34+
subscription.observation += '\n\nAtivada via comando automático do servidor.'
35+
subscription.status = Subscription.Status.ACTIVE
36+
subscription.save()

pythonpro/memberkit/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,6 @@ class Status(models.TextChoices):
4343
responsible = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING, null=True,
4444
related_name='created_subscriptions')
4545
observation = models.TextField(verbose_name='Observação', blank=True, default='')
46+
47+
def __str__(self):
48+
return f'Assinatura: {self.id} de {self.subscriber}'

pythonpro/memberkit/tests/test_commands.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,53 @@ def test_synchronize_paid_subscriptions(db):
2525
baker.make(PagarmeNotification, payment=payment, status=pagarme_facade.PAID)
2626
baker.make(PagarmeNotification, payment=payment, status=pagarme_facade.REFUNDED)
2727
management.call_command('synchronize_paid_subscriptions')
28-
assert 2 == Subscription.objects.count()
28+
assert 2 == Subscription.objects.filter(status=Subscription.Status.INACTIVE).count()
29+
30+
31+
def test_fix_inactive_subscriptions(db):
32+
payment_config = baker.make(PagarmeItemConfig)
33+
inactive_with_paid_payment = _make_subscriptions_with_payment(payment_config, pagarme_facade.PAID)
34+
unpaid_statuses = set(pagarme_facade._impossible_states)
35+
unpaid_statuses.discard(pagarme_facade.PAID)
36+
for status in unpaid_statuses:
37+
# only one will have PAID status
38+
_make_subscriptions_with_payment(payment_config, status)
39+
40+
# Make one refunded Subscription
41+
payment = baker.make(PagarmePayment, user=baker.make(User))
42+
payment.items.set([payment_config])
43+
baker.make(PagarmeNotification, payment=payment, status=pagarme_facade.PAID)
44+
baker.make(PagarmeNotification, payment=payment, status=pagarme_facade.REFUNDED)
45+
refunded_subscription = baker.make(Subscription, payment=payment, status=Subscription.Status.INACTIVE)
46+
47+
# Make one subscriptions with no payment at all
48+
baker.make(Subscription, status=Subscription.Status.INACTIVE)
49+
active_without_payment = baker.make(Subscription, status=Subscription.Status.ACTIVE)
50+
51+
active_with_paid_payment = _make_subscriptions_with_payment(payment_config, pagarme_facade.PAID)
52+
active_with_paid_payment.status = Subscription.Status.ACTIVE
53+
active_with_paid_payment.save()
54+
55+
previous_subscriptions = Subscription.objects.count()
56+
assert 2 == Subscription.objects.filter(status=Subscription.Status.ACTIVE).count()
57+
58+
management.call_command('fix_inactive_subscriptions')
59+
60+
assert previous_subscriptions == Subscription.objects.count()
61+
assert 3 == Subscription.objects.filter(status=Subscription.Status.ACTIVE).count()
62+
assert not Subscription.objects.filter(status=Subscription.Status.ACTIVE, id=refunded_subscription.id).exists()
63+
64+
appended_observation_message = '\n\nAtivada via comando automático do servidor.'
65+
active_without_payment.refresh_from_db()
66+
assert not active_without_payment.observation.endswith(appended_observation_message)
67+
active_with_paid_payment.refresh_from_db()
68+
assert not active_with_paid_payment.observation.endswith(appended_observation_message)
69+
inactive_with_paid_payment.refresh_from_db()
70+
assert inactive_with_paid_payment.observation.endswith(appended_observation_message)
71+
72+
73+
def _make_subscriptions_with_payment(payment_config, status):
74+
payment = baker.make(PagarmePayment, user=baker.make(User))
75+
payment.items.set([payment_config])
76+
baker.make(PagarmeNotification, payment=payment, status=status)
77+
return baker.make(Subscription, payment=payment, status=Subscription.Status.INACTIVE)

0 commit comments

Comments
 (0)