개발일기

[구독 해지예약 및 취소, 구독 재신청 구현] 본문

Project Portfolio

[구독 해지예약 및 취소, 구독 재신청 구현]

츄98 2023. 6. 10. 00:29

crontab을 활용하여 해지예약 및 취소, 구독 재신청 구현하기

- models.py

# models.py
class Subscribe(CommonModel):
    """소비자구독"""

    user = models.OneToOneField(
        "users.User", related_name="subscribe_data", on_delete=models.CASCADE
    )
    subscribe = models.BooleanField("구독여부", default=True, null=False)
    is_cancel = models.BooleanField("예약해지여부", default=False, null=True)
    next_payment = models.DateField("다음결제일")

    def __str__(self):
        return str(self.user.nickname) + str(self.subscribe) + str(self.next_payment)

- views.py

"""구독"""


class SubscribeView(APIView):
    permission_classes = [IsAuthenticated]

    # 구독 정보 가져오기
    def get(self, request):
        subscription = get_object_or_404(Subscribe, user_id=request.user.id)
        serializer = SubscriptionInfoSerializer(subscription)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # 구독 최초 생성
    def post(self, request):

        serializer = SubscriptionSerializer(data=request.data)
        if serializer.is_valid():
            try:
                Point.objects.create(user=request.user, point_type_id=6, point=9900)
                serializer.save(user=request.user,
                                next_payment=timezone.now().date() + timedelta(weeks=4))
                return Response({"message": "성공!"}, status=status.HTTP_200_OK)
            except:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # 구독해지 및 복구
    def patch(self, request):
        subscription = get_object_or_404(Subscribe, user_id=request.user.id)
        if (subscription.subscribe == True) and (subscription.is_cancel == False):
            subscription.is_cancel = True
            subscription.save()
            return Response({"message": "해지예약"}, status.HTTP_200_OK)
        elif (subscription.subscribe == True) and (subscription.is_cancel == True):
            subscription.is_cancel = False
            subscription.save()
            return Response({"message": "해지예약 취소"}, status.HTTP_200_OK)
        else:
            total_point = PointStatisticView.get_total_point(request.user)
            if total_point >= 9900:
                Point.objects.create(user=request.user, point_type_id=6, point= 9900)
                subscription.subscribe = True
                subscription.next_payment = timezone.now().date() + timedelta(weeks=4)
                subscription.save()
                return Response({"message": "성공!"}, status.HTTP_200_OK)
            else:
                return Response({"message": "잔액부족"}, status.HTTP_400_BAD_REQUEST)

 

해지예약이기 때문에 사용자가 해지신청을 하면, is_cancel = True가 된다.

해지는 다음결제일에 진행이 되기 때문에 해지신청을 한다고해서 당장 사용자에게 달라지는 것은 없다.

만일 사용자가 구독기간 중 마음이 바뀌어서 해지예약을 취소하길 원할 경우, 

다른 변화없이 is_cancel = False로 바뀐다. 그리고 다음결제일에 정상결제가 진행될 것이다.

 

해지예약을 한 상태에서 다음결제일이 되면, crontab이 돌면서 해지를 하게 된다.

코드를 아래와 같다.

 

# crontab.py

cancel_users = Subscribe.objects.filter(next_payment=timezone.now().date(), subscribe=True, is_cancel=True)
        
# 구독취소
for cancel_user in cancel_users:
    with transaction.atomic():
        cancel_user.subscribe = False
        cancel_user.is_cancel = False
        cancel_user.save()

 

구독이 취소된 상태에서 사용자가 재구독을 하고 싶다면,

subscribe = False인 상태이기 때문에 포인트결제와 함께 subscribe = True가 된다.

 

크론탭에 대한 더 자세한 설명이 보고 싶다면,

아래 글을 참고하면 된다.

2023.06.09 - [Project Portfolio] - [Django] Schedule과 crontab 사용하기