Beispiel #1
0
    def test_get_plan_list(self):
        PlanFactory.create_batch(40)

        url = reverse('plan-list')

        response = self.client.get(url)

        full_url = None
        for field in response.data:
            full_url = field.get('url', None)
            if full_url:
                break
        if full_url:
            domain = full_url.split('/')[2]
            full_url = full_url.split(domain)[0] + domain + url

        assert response.status_code == status.HTTP_200_OK
        assert response._headers['link'] == \
            ('Link', '<' + full_url + '?page=2>; rel="next", ' +
             '<' + full_url + '?page=1>; rel="first", ' +
             '<' + full_url + '?page=2> rel="last"')

        response = self.client.get(url + '?page=2')

        assert response.status_code == status.HTTP_200_OK
        assert response._headers['link'] == \
            ('Link', '<' + full_url + '>; rel="prev", ' +
             '<' + full_url + '?page=1>; rel="first", ' +
             '<' + full_url + '?page=2> rel="last"')
Beispiel #2
0
    def test_get_plan_list(self):
        PlanFactory.create_batch(40)

        url = reverse('plan-list')

        response = self.client.get(url)

        full_url = None
        for field in response.data:
            full_url = field.get('url', None)
            if full_url:
                break
        if full_url:
            domain = full_url.split('/')[2]
            full_url = full_url.split(domain)[0] + domain + url

        assert response.status_code == status.HTTP_200_OK
        assert response._headers['link'] == \
            ('Link', '<' + full_url + '?page=2; rel="next">, ' +
             '<' + full_url + '?page=1; rel="first">, ' +
             '<' + full_url + '?page=2; rel="last">')

        response = self.client.get(url + '?page=2')

        assert response.status_code == status.HTTP_200_OK
        assert response._headers['link'] == \
            ('Link', '<' + full_url + '; rel="prev">, ' +
             '<' + full_url + '?page=1; rel="first">, ' +
             '<' + full_url + '?page=2; rel="last">')
    def create_basic_plan(self,
                          start_date,
                          end_date,
                          interval=Plan.INTERVALS.YEAR):
        self.provider = ProviderFactory.create(flow=Provider.FLOWS.INVOICE)

        self.customer = CustomerFactory.create(
            consolidated_billing=False, sales_tax_percent=Decimal('0.00'))
        self.currency = 'USD'

        self.plan = PlanFactory.create(
            interval=interval,
            interval_count=1,
            generate_after=0,
            enabled=True,
            provider=self.provider,
            product_code=ProductCodeFactory(value="yearly-seat-plan"),
            amount=Decimal('10.00'),
            prebill_plan=False,
            currency=self.currency,
            trial_period_days=None,
            cycle_billing_duration=dt.timedelta(days=1),
        )
        self.plan.save()

        # Create the prorated subscription
        self.subscription = SubscriptionFactory.create(plan=self.plan,
                                                       start_date=start_date,
                                                       customer=self.customer)
        self.subscription.activate()
        self.subscription.save()
    def test_already_billed_sub_wa_cb_on_trial_last_billing_date(self):
        plan = PlanFactory.create(generate_after=100,
                                  interval=Plan.INTERVALS.MONTH,
                                  interval_count=1)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12),
            trial_end=datetime.date(2015, 9, 12)
        )
        correct_billing_date = datetime.date(2015, 8, 12)
        incorrect_billing_date_1 = datetime.date(2015, 8, 11)

        false_property = PropertyMock(return_value=False)
        mocked_on_trial = MagicMock(return_value=True)
        mocked_last_billing_date = PropertyMock(
            return_value=datetime.date(2015, 9, 2)
        )
        mocked_bucket_end_date = MagicMock(
            return_value=datetime.date(2015, 9, 12)
        )
        with patch.multiple(
            Subscription,
            is_billed_first_time=false_property,
            on_trial=mocked_on_trial,
            last_billing_date=mocked_last_billing_date,
            _has_existing_customer_with_consolidated_billing=false_property,
            bucket_end_date=mocked_bucket_end_date
        ):
            assert subscription.should_be_billed(correct_billing_date) is True
            assert subscription.should_be_billed(incorrect_billing_date_1) is False
Beispiel #5
0
    def test_already_billed_sub_wa_cb(self):
        plan = PlanFactory.create(generate_after=100)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 1, 1)
        )
        correct_billing_date = datetime.date(2015, 10, 1)
        incorrect_billing_date_1 = datetime.date(2015, 9, 3)
        incorrect_billing_date_2 = datetime.date(2015, 9, 12)
        incorrect_billing_date_3 = datetime.date(2015, 9, 30)

        false_property = PropertyMock(return_value=False)
        mocked_on_trial = MagicMock(return_value=True)
        mocked_last_billing_date = PropertyMock(
            return_value=datetime.date(2015, 9, 2)
        )
        mocked_bucket_end_date = MagicMock(
            return_value=datetime.date(2015, 9, 30)
        )
        with patch.multiple(
            Subscription,
            is_billed_first_time=false_property,
            on_trial=mocked_on_trial,
            last_billing_date=mocked_last_billing_date,
            _has_existing_customer_with_consolidated_billing=false_property,
            bucket_end_date=mocked_bucket_end_date
        ):
            assert subscription.should_be_billed(correct_billing_date) is True
            assert subscription.should_be_billed(incorrect_billing_date_1) is False
            assert subscription.should_be_billed(incorrect_billing_date_2) is False
            assert subscription.should_be_billed(incorrect_billing_date_3) is False
    def test_new_active_sub_trial_end_different_month_from_start_date_w_cb(self):
        plan = PlanFactory.create(generate_after=100)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12),
            trial_end=datetime.date(2015, 9, 12)
        )
        correct_billing_date_1 = datetime.date(2015, 9, 1)
        correct_billing_date_2 = datetime.date(2015, 8, 12)
        incorrect_billing_date_1 = datetime.date(2015, 8, 11)
        incorrect_billing_date_2 = datetime.date(2015, 7, 3)

        true_property = PropertyMock(return_value=True)
        mocked_bucket_end_date = MagicMock(
            return_value=datetime.date(2015, 8, 31)
        )
        with patch.multiple(
            Subscription,
            is_billed_first_time=true_property,
            _has_existing_customer_with_consolidated_billing=true_property,
            bucket_end_date=mocked_bucket_end_date
        ):
            assert subscription.should_be_billed(correct_billing_date_1) is True
            assert subscription.should_be_billed(correct_billing_date_2) is True
            assert subscription.should_be_billed(incorrect_billing_date_1) is False
            assert subscription.should_be_billed(incorrect_billing_date_2) is False
    def test_canceled_sub_with_billed_plan_but_not_metered_features_1(self):
        plan = PlanFactory.create(generate_after=100,
                                  interval=Plan.INTERVALS.MONTH,
                                  interval_count=1)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 1, 1),
            cancel_date=datetime.date(2018, 1, 20)
        )

        billing_log = BillingLog.objects.create(
            subscription=subscription,
            billing_date=datetime.date(2015, 9, 2),
            plan_billed_up_to=datetime.date(2018, 1, 31),
            metered_features_billed_up_to=datetime.date(2017, 12, 31)
        )

        correct_billing_date_1 = subscription.cancel_date + datetime.timedelta(days=1)
        correct_billing_date_2 = datetime.date(2018, 2, 1)
        incorrect_billing_date = correct_billing_date_1 - datetime.timedelta(days=1)

        assert \
            billing_log.metered_features_billed_up_to \
            < incorrect_billing_date \
            <= subscription.cancel_date \
            < correct_billing_date_1 \
            < billing_log.plan_billed_up_to \
            < correct_billing_date_2 \

        assert subscription.should_be_billed(correct_billing_date_1)
        assert subscription.should_be_billed(correct_billing_date_2)
        assert not subscription.should_be_billed(incorrect_billing_date)
Beispiel #8
0
    def test_new_active_sub_trial_end_different_month_from_start_date_w_cb(self):
        plan = PlanFactory.create(generate_after=100)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12),
            trial_end=datetime.date(2015, 9, 12)
        )
        correct_billing_date = datetime.date(2015, 9, 1)
        incorrect_billing_date_1 = datetime.date(2015, 8, 12)
        incorrect_billing_date_2 = datetime.date(2015, 8, 13)
        incorrect_billing_date_3 = datetime.date(2015, 8, 31)

        true_property = PropertyMock(return_value=True)
        mocked_bucket_end_date = MagicMock(
            return_value=datetime.date(2015, 8, 31)
        )
        with patch.multiple(
            Subscription,
            is_billed_first_time=true_property,
            _has_existing_customer_with_consolidated_billing=true_property,
            bucket_end_date=mocked_bucket_end_date
        ):
            assert subscription.should_be_billed(correct_billing_date) is True
            assert subscription.should_be_billed(incorrect_billing_date_1) is False
            assert subscription.should_be_billed(incorrect_billing_date_2) is False
            assert subscription.should_be_billed(incorrect_billing_date_3) is False
Beispiel #9
0
    def test_already_billed_sub_wa_cb(self):
        plan = PlanFactory.create(generate_after=100,
                                  interval=Plan.INTERVALS.MONTH,
                                  interval_count=1)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 1, 1))
        correct_billing_date = datetime.date(2015, 10, 1)
        incorrect_billing_date_1 = datetime.date(2015, 9, 3)
        incorrect_billing_date_2 = datetime.date(2015, 9, 12)
        incorrect_billing_date_3 = datetime.date(2015, 9, 30)

        BillingLog.objects.create(subscription=subscription,
                                  billing_date=datetime.date(2015, 9, 2),
                                  plan_billed_up_to=datetime.date(2015, 9, 30),
                                  metered_features_billed_up_to=datetime.date(
                                      2015, 9, 2))

        assert subscription.should_be_billed(correct_billing_date, NOW) is True
        assert subscription.should_be_billed(incorrect_billing_date_1,
                                             NOW) is False
        assert subscription.should_be_billed(incorrect_billing_date_2,
                                             NOW) is False
        assert subscription.should_be_billed(incorrect_billing_date_3,
                                             NOW) is False
Beispiel #10
0
    def test_already_billed_sub_w_cb_on_trial_last_billing_date(self):
        plan = PlanFactory.create(generate_after=100)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12),
            trial_end=datetime.date(2015, 9, 12))
        correct_billing_date_1 = datetime.date(2015, 10, 1)
        correct_billing_date_2 = datetime.date(2015, 9, 12)
        correct_billing_date_3 = datetime.date(2015, 8, 12)
        incorrect_billing_date = datetime.date(2015, 8, 11)

        true_property = PropertyMock(return_value=True)
        false_property = PropertyMock(return_value=False)
        mocked_on_trial = MagicMock(return_value=True)
        mocked_last_billing_date = PropertyMock(
            return_value=datetime.date(2015, 9, 2))
        with patch.multiple(
                Subscription,
                is_billed_first_time=false_property,
                on_trial=mocked_on_trial,
                last_billing_date=mocked_last_billing_date,
                _has_existing_customer_with_consolidated_billing=true_property,
        ):
            assert subscription.should_be_billed(correct_billing_date_1,
                                                 NOW) is True
            assert subscription.should_be_billed(correct_billing_date_2,
                                                 NOW) is True
            assert subscription.should_be_billed(correct_billing_date_3,
                                                 NOW) is True
            assert subscription.should_be_billed(incorrect_billing_date,
                                                 NOW) is False
Beispiel #11
0
    def test_patch_plan_non_editable_field(self):
        plan = PlanFactory.create()

        url = reverse("plan-detail", kwargs={"pk": plan.pk})

        response = self.client.patch(url, json.dumps({"currency": "DollaDolla"}), content_type="application/json")
        self.assertNotEqual(response.data["currency"], "DollaDolla")
        self.assertEqual(response.status_code, status.HTTP_200_OK)
Beispiel #12
0
    def test_get_plan_list(self):
        PlanFactory.create_batch(40)

        url = reverse("plan-list")

        response = self.client.get(url)

        full_url = None
        for field in response.data:
            full_url = field.get("url", None)
            if full_url:
                break
        if full_url:
            domain = full_url.split("/")[2]
            full_url = full_url.split(domain)[0] + domain + url

        assert response.status_code == status.HTTP_200_OK
        assert response._headers["link"] == (
            "Link",
            "<"
            + full_url
            + '?page=2; rel="next">, '
            + "<"
            + full_url
            + '?page=1; rel="first">, '
            + "<"
            + full_url
            + '?page=2; rel="last">',
        )

        response = self.client.get(url + "?page=2")

        assert response.status_code == status.HTTP_200_OK
        assert response._headers["link"] == (
            "Link",
            "<"
            + full_url
            + '; rel="prev">, '
            + "<"
            + full_url
            + '?page=1; rel="first">, '
            + "<"
            + full_url
            + '?page=2; rel="last">',
        )
Beispiel #13
0
    def test_get_plan_detail(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.get(url)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertNotEqual(response.data, [])
Beispiel #14
0
    def test_new_active_sub_with_smaller_billing_date_than_start_date(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 22))
        billing_date = datetime.date(2015, 8, 10)

        assert subscription.should_be_billed(billing_date) is False
Beispiel #15
0
    def test_get_plan_detail(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.get(url)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertNotEqual(response.data, [])
Beispiel #16
0
    def test_put_plan(self):
        plan = PlanFactory.create()

        url = reverse("plan-detail", kwargs={"pk": plan.pk})

        response = self.client.put(url)

        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
        self.assertEqual(response.data, {u"detail": u'Method "PUT" not allowed.'})
Beispiel #17
0
    def test_canceled_sub_w_date_before_cancel_date(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            cancel_date=datetime.date(2015, 8, 22),
            start_date=datetime.date(2015, 8, 1))
        incorrect_billing_date = datetime.date(2015, 8, 10)

        assert subscription.should_be_billed(incorrect_billing_date) is False
Beispiel #18
0
    def test_patch_plan_non_editable_field(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.patch(url,
                                     json.dumps({"currency": "DollaDolla"}),
                                     content_type='application/json')
        self.assertNotEqual(response.data['currency'], 'DollaDolla')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
Beispiel #19
0
    def test_new_active_sub_with_smaller_billing_date_than_start_date(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 22)
        )
        billing_date = datetime.date(2015, 8, 10)

        assert subscription.should_be_billed(billing_date) is False
Beispiel #20
0
    def test_canceled_sub_w_date_before_cancel_date(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            cancel_date=datetime.date(2015, 8, 22),
            start_date=datetime.date(2015, 8, 1)
        )
        incorrect_billing_date = datetime.date(2015, 8, 10)

        assert subscription.should_be_billed(incorrect_billing_date) is False
Beispiel #21
0
    def test_delete_plan(self):
        plan = PlanFactory.create()
        plan.enabled = True
        plan.save()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.delete(url)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, {"deleted": True})
Beispiel #22
0
 def test_updateable_buckets_2_months_canceled_subscription_last_month(self):
     plan = PlanFactory.create(generate_after=24 * 60,
                               interval=Plan.INTERVALS.MONTH,
                               interval_count=1)
     subscription = SubscriptionFactory.create(
         plan=plan,
         state=Subscription.STATES.CANCELED,
         start_date=datetime.date(2014, 1, 1),
         cancel_date=datetime.date(2014, 12, 31)
     )
     assert subscription.updateable_buckets() == []
Beispiel #23
0
    def test_patch_plan(self):
        plan = PlanFactory.create()

        url = reverse("plan-detail", kwargs={"pk": plan.pk})

        response = self.client.patch(
            url, json.dumps({"name": "Hydrogen", "generate_after": 86400}), content_type="application/json"
        )
        self.assertEqual(response.data["name"], "Hydrogen")
        self.assertEqual(response.data["generate_after"], 86400)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
Beispiel #24
0
    def test_put_plan(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.put(url)

        self.assertEqual(response.status_code,
                         status.HTTP_405_METHOD_NOT_ALLOWED)
        self.assertEqual(response.data,
                         {u'detail': u'Method "PUT" not allowed.'})
 def plan(self, **kwargs):
     return PlanFactory.create(
         generate_after=0,
         enabled=True,
         product_code=ProductCodeFactory(value="monthly-deliv-plan"),
         amount=Decimal('10.00'),
         prebill_plan=False,
         currency='USD',
         trial_period_days=None,
         # cycle_billing_duration=dt.timedelta(days=1),
         **kwargs)
Beispiel #26
0
    def test_delete_plan(self):
        plan = PlanFactory.create()
        plan.enabled = True
        plan.save()

        url = reverse('plan-detail', kwargs={'pk': 1})

        response = self.client.delete(url)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, {"deleted": True})
    def setUp(self):
        # Setup simple subscription
        self.plan = PlanFactory.create(interval=Plan.INTERVALS.MONTH,
                                       interval_count=1, generate_after=120,
                                       enabled=True, amount=Decimal('200.00'),
                                       trial_period_days=0)

        self.subscription = SubscriptionFactory.create(plan=self.plan,
                                                       start_date=self.date)
        self.subscription.activate()
        self.subscription.save()
Beispiel #28
0
    def test_patch_plan(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.patch(url, json.dumps({
            "name": "Hydrogen",
            "generate_after": 86400
        }), content_type='application/json')
        self.assertEqual(response.data['name'], 'Hydrogen')
        self.assertEqual(response.data['generate_after'], 86400)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
Beispiel #29
0
    def test_patch_plan(self):
        plan = PlanFactory.create()

        url = reverse('plan-detail', kwargs={'pk': plan.pk})

        response = self.client.patch(url, json.dumps({
            "name": "Hydrogen",
            "generate_after": 86400
        }), content_type='application/json')
        self.assertEqual(response.data['name'], 'Hydrogen')
        self.assertEqual(response.data['generate_after'], 86400)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
Beispiel #30
0
 def test_updateable_buckets_active_subscription(self):
     plan = PlanFactory.create(generate_after=24 * 60,
                               interval=Plan.INTERVALS.MONTH,
                               interval_count=1)
     subscription = SubscriptionFactory.create(
         plan=plan,
         state=Subscription.STATES.ACTIVE,
         start_date=datetime.date(2015, 1, 1)
     )
     assert subscription.updateable_buckets() == [
         {'start_date': datetime.date(2015, 1, 1), 'end_date': datetime.date(2015, 1, 31)},
     ]
Beispiel #31
0
    def setUp(self):
        # Setup simple subscription
        self.plan = PlanFactory.create(interval=Plan.INTERVALS.MONTH,
                                       interval_count=1,
                                       generate_after=120,
                                       enabled=True,
                                       amount=Decimal('200.00'),
                                       trial_period_days=0)

        self.subscription = SubscriptionFactory.create(plan=self.plan,
                                                       start_date=self.date)
        self.subscription.activate()
        self.subscription.save()
Beispiel #32
0
    def test_create_post_subscription(self):
        plan = PlanFactory.create()
        customer = CustomerFactory.create()

        plan_url = reverse('plan-detail', kwargs={'pk': plan.pk})

        url = reverse('subscription-list', kwargs={'customer_pk': customer.pk})

        response = self.client.post(url, json.dumps({
            "plan": plan_url,
            "trial_end": '2014-12-07',
            "start_date": '2014-11-19'
        }), content_type='application/json')
        assert response.status_code == status.HTTP_201_CREATED
Beispiel #33
0
    def test_canceled_sub_wa_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 8, 10),
            cancel_date=datetime.date(2015, 8, 22))
        correct_billing_date = datetime.date(2015, 8, 23)

        false_property = PropertyMock(return_value=False)
        with patch.multiple(
                Subscription,
                _has_existing_customer_with_consolidated_billing=false_property
        ):
            assert subscription.should_be_billed(correct_billing_date) is True
Beispiel #34
0
    def test_canceled_sub_wa_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 8, 10),
            cancel_date=datetime.date(2015, 8, 22)
        )
        correct_billing_date = datetime.date(2015, 8, 23)

        false_property = PropertyMock(return_value=False)
        with patch.multiple(
            Subscription,
            _has_existing_customer_with_consolidated_billing=false_property
        ):
            assert subscription.should_be_billed(correct_billing_date) is True
Beispiel #35
0
    def test_sub_canceled_now_w_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 8, 10),
            cancel_date=datetime.date(2015, 8, 22))
        billing_date_1 = datetime.date(2015, 9, 1)
        billing_date_2 = datetime.date(2015, 8, 23)

        true_property = PropertyMock(return_value=True)
        with patch.multiple(
                Subscription,
                _has_existing_customer_with_consolidated_billing=true_property
        ):
            assert subscription.should_be_billed(billing_date_1, NOW) is True
            assert subscription.should_be_billed(billing_date_2, NOW) is True
Beispiel #36
0
    def test_create_post_subscription_reference(self):
        plan = PlanFactory.create()
        customer = CustomerFactory.create()

        plan_url = reverse('plan-detail', kwargs={'pk': plan.pk})

        url = reverse('subscription-list', kwargs={'customer_pk': customer.pk})

        test_reference = 'test reference'
        response = self.client.post(url, json.dumps({
            "plan": plan_url,
            "start_date": '2014-11-19',
            "reference": test_reference,
        }), content_type='application/json')

        assert response.status_code == status.HTTP_201_CREATED

        assert response.data["reference"] == test_reference
Beispiel #37
0
    def test_sub_canceled_at_end_of_bc_w_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 8, 22),
            cancel_date=datetime.date(2015, 9, 1))
        correct_billing_date = datetime.date(2015, 9, 2)
        incorrect_billing_date = datetime.date(2015, 8, 22)

        true_property = PropertyMock(return_value=True)
        with patch.multiple(
                Subscription,
                _has_existing_customer_with_consolidated_billing=true_property
        ):
            assert subscription.should_be_billed(correct_billing_date,
                                                 NOW) is True
            assert subscription.should_be_billed(incorrect_billing_date,
                                                 NOW) is False
Beispiel #38
0
    def test_new_active_sub_no_trial_wa_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12)
        )
        correct_billing_date_1 = datetime.date(2015, 8, 12)
        correct_billing_date_2 = datetime.date(2015, 8, 20)

        true_property = PropertyMock(return_value=True)
        false_property = PropertyMock(return_value=False)
        with patch.multiple(
            Subscription,
            is_billed_first_time=true_property,
            _has_existing_customer_with_consolidated_billing=false_property,
        ):
            assert subscription.should_be_billed(correct_billing_date_1) is True
            assert subscription.should_be_billed(correct_billing_date_2) is True
Beispiel #39
0
    def test_new_active_sub_no_trial_wa_consolidated_billing(self):
        plan = PlanFactory.create(generate_after=120)
        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.ACTIVE,
            start_date=datetime.date(2015, 8, 12)
        )
        correct_billing_date_1 = datetime.date(2015, 8, 12)
        correct_billing_date_2 = datetime.date(2015, 8, 20)

        true_property = PropertyMock(return_value=True)
        false_property = PropertyMock(return_value=False)
        with patch.multiple(
            Subscription,
            is_billed_first_time=true_property,
            _has_existing_customer_with_consolidated_billing=false_property,
        ):
            assert subscription.should_be_billed(correct_billing_date_1) is True
            assert subscription.should_be_billed(correct_billing_date_2) is True
    def test_create_post_subscription_reference(self):
        plan = PlanFactory.create()
        customer = CustomerFactory.create()

        plan_url = reverse('plan-detail', kwargs={'pk': plan.pk})

        url = reverse('subscription-list', kwargs={'customer_pk': customer.pk})

        test_reference = 'test reference'
        response = self.client.post(url,
                                    json.dumps({
                                        "plan": plan_url,
                                        "start_date": '2014-11-19',
                                        "reference": test_reference,
                                    }),
                                    content_type='application/json')

        assert response.status_code == status.HTTP_201_CREATED

        assert response.data["reference"] == test_reference
Beispiel #41
0
    def test_create_post_subscription_description(self):
        plan = PlanFactory.create()
        customer = CustomerFactory.create()

        plan_url = reverse('plan-detail', kwargs={'pk': plan.pk})

        url = reverse('subscription-list', kwargs={'customer_pk': customer.pk})

        test_description = 'test description'
        response = self.client.post(url, json.dumps({
            "plan": plan_url,
            "start_date": '2014-11-19',
            "description": test_description,
        }), content_type='application/json')

        assert response.status_code == status.HTTP_201_CREATED

        assert response.data["description"] == test_description

        subscription = Subscription.objects.get(id=response.data['id'])
        assert response.data == spec_subscription(subscription)
Beispiel #42
0
    def test_canceled_sub_with_billed_plan_but_not_metered_features_2(self):
        # Like previous test, but this time there's cycle_billing_duration added to the mix
        plan = PlanFactory.create(
            generate_after=100,
            interval=Plan.INTERVALS.MONTH,
            interval_count=1,
            cycle_billing_duration=datetime.timedelta(days=5))

        subscription = SubscriptionFactory.create(
            plan=plan,
            state=Subscription.STATES.CANCELED,
            start_date=datetime.date(2015, 1, 1),
            cancel_date=datetime.date(2018, 1, 20))

        billing_log = BillingLog.objects.create(
            subscription=subscription,
            billing_date=datetime.date(2015, 9, 2),
            plan_billed_up_to=datetime.date(2018, 1, 31),
            metered_features_billed_up_to=datetime.date(2017, 12, 31))

        correct_billing_date = datetime.date(2018, 2, 1)
        incorrect_billing_date_1 = subscription.cancel_date + datetime.timedelta(
            days=1)
        incorrect_billing_date_2 = correct_billing_date - datetime.timedelta(
            days=1)

        assert \
            billing_log.metered_features_billed_up_to \
            < subscription.cancel_date \
            < incorrect_billing_date_1 \
            < incorrect_billing_date_2 \
            <= billing_log.plan_billed_up_to \
            < correct_billing_date

        assert subscription.should_be_billed(correct_billing_date, NOW)
        assert not subscription.should_be_billed(incorrect_billing_date_1, NOW)
        assert not subscription.should_be_billed(incorrect_billing_date_2, NOW)
Beispiel #43
0
    def test_subscription_transaction_declined_suspend(self):
        """ Confirm that a failed transaction can trigger a subscription
        to suspend. """

        # We'll create a plan that starts here
        start_date = dt.date(2019, 1, 1)

        # And the trial date ends here too
        trial_end_date = dt.date(2019, 1, 1)

        # The customer will use some metered features here
        metered_usage_on = dt.date(2019, 1, 10)

        # Docs will be generated to bill here.
        prev_billing_date = dt.date(2019, 1, 3)

        # So, the customer grace period ends here.
        #  First billing interval:  dt.date(2019, 2, 1)
        #
        billing_grace_exp = dt.date(2019, 2, 3)

        # The next billing check should discover that the subscription
        # is unpaid.
        #   Billing due date is:       dt.date(2019, 2, 6)
        #   With the grace period:     dt.date(2019, 2, 9)
        #
        billing_post_grace_check = dt.date(2019, 2, 10)

        # Create a customer
        #
        customer = CustomerFactory.create(sales_tax_percent=Decimal('0.00'),
                                          payment_due_days=3)
        PaymentMethodFactory.create(
            payment_processor=triggered_processor,
            customer=customer,
            canceled=False,
            verified=True,
        )

        # Create a metered feature
        #
        mf_price = Decimal('2.5')
        metered_feature = MeteredFeatureFactory(
            included_units_during_trial=Decimal('0.00'),
            price_per_unit=mf_price)
        currency = 'USD'

        # Crate a plan with metered features. Generate the invoice after
        # the 5 day trial period, the plan will be billed every 30 days.
        #
        generate_after = 5
        plan = PlanFactory.create(interval=Plan.INTERVALS.DAY,
                                  interval_count=30,
                                  generate_after=generate_after,
                                  enabled=True,
                                  amount=Decimal('20.00'),
                                  trial_period_days=1,
                                  metered_features=[metered_feature],
                                  currency=currency)

        # Subscribe the customer
        #
        subscription = SubscriptionFactory.create(plan=plan,
                                                  start_date=start_date,
                                                  customer=customer)
        subscription.activate()
        subscription.save()

        # Log some metered usage
        consumed_1 = Decimal('5.00')
        consumed_2 = Decimal('5.00')
        mf_log = MeteredFeatureUnitsLogFactory.create(
            subscription=subscription,
            metered_feature=metered_feature,
            start_date=metered_usage_on,
            end_date=subscription.trial_end,
            consumed_units=consumed_1)

        # Generate the docs
        call_command('generate_docs',
                     billing_date=prev_billing_date,
                     stdout=self.output)

        proforma = Proforma.objects.first()

        assert proforma.proforma_entries.count() != 0
        assert Subscription.objects.all().count() == 1
        assert Invoice.objects.all().count() == 0
        assert Proforma.objects.all()[0].total > Decimal('0.00')

        # Consume more units
        mf_log.consumed_units += consumed_2
        mf_log.save()

        call_command('generate_docs',
                     billing_date=billing_grace_exp,
                     stdout=self.output)

        assert Proforma.objects.all().count() != 0
        assert Invoice.objects.all().count() == 0

        for pf in Proforma.objects.all():
            # # Issue the proforma to generate transactions
            # proforma = Proforma.objects.all()[1]
            pf.issue()
            pf.save()

            self.assertEqual(pf.state, Proforma.STATES.ISSUED)
            # Fail the transaction
            for tx in pf.transactions:
                # tx = proforma.transactions[0]
                tx.fail()
                tx.save()
                self.assertEqual(tx.state, Transaction.States.Failed)

        assert Transaction.objects.all().count() != 0

        call_command('check_subscriptions',
                     billing_date=billing_post_grace_check,
                     stdout=self.output)

        subscr = Subscription.objects.first()

        # Scan for subscriptions with unpaid documents
        logging.debug("subscr %s" % subscr)
        self.assertEqual(subscr.state, Subscription.STATES.CANCELED)
    def test_issued_date_works_as_expected(self):
        """ Test that usage under and above a certain amount tracks with
        assumptions. """

        # Set up the timescale.
        start_date = dt.date(2018, 1, 1)
        first_invoice_date = dt.date(2018, 2, 1)

        prev_billing_date = generate_docs_date('2018-01-01')
        period_end_date = generate_docs_date('2018-01-30')
        curr_billing_date = generate_docs_date('2018-01-31')
        next_billing_date = generate_docs_date('2018-02-01')

        seat_feature_usage_set = dt.date(2018, 1, 1)
        feature_usage_start = dt.date(2018, 1, 2)
        feature_usage_end = dt.date(2018, 1, 30)

        provider = self.provider
        customer = self.customer
        currency = 'USD'

        seat_feature = self.seat_feature
        seat_feature.save()

        metered_feature = self.metered_feature
        metered_feature.save()

        plan = PlanFactory.create(
            interval=Plan.INTERVALS.MONTH,
            interval_count=1,
            generate_after=0,
            enabled=True,
            provider=provider,
            product_code=ProductCodeFactory(value="monthly-deliv-plan"),
            amount=Decimal('10.00'),
            prebill_plan=False,
            currency=currency,
            trial_period_days=None,
            cycle_billing_duration=dt.timedelta(days=1),
            metered_features=[metered_feature])
        plan.save()

        # Create the prorated subscription
        subscription = SubscriptionFactory.create(plan=plan,
                                                  start_date=start_date,
                                                  customer=customer)
        subscription.activate()
        subscription.save()

        call_command('generate_docs',
                     date=feature_usage_start,
                     stdout=self.output)

        # Track some usage
        mf = MeteredFeatureUnitsLogFactory.create(
            subscription=subscription,
            metered_feature=metered_feature,
            start_date=feature_usage_start,
            end_date=feature_usage_end,
            consumed_units=Decimal('20.00'))
        mf.save()

        call_command('generate_docs',
                     date=next_billing_date,
                     stdout=self.output)

        assert Invoice.objects.all().count() == 1
        invoice = Invoice.objects.all().first()

        assert invoice.issue_date == next_billing_date
        assert invoice.total == Decimal(110.0)
    def test_subscription_yearly_proration_isnt_borked_half(self):
        from django.db.models import Q

        # Set up the timescale.
        start_date = dt.date(2018, 1, 1)
        end_date = dt.date(2018, 7, 1)
        freezer = freeze_time('2018-07-01')
        first_billing_date = generate_docs_date('2018-01-01')
        end_billing_date = generate_docs_date('2018-07-02')

        feature_usage_set = dt.date(2018, 1, 1)
        fst_feature_usage_start = dt.date(2018, 1, 2)
        snd_feature_usage_end = dt.date(2018, 1, 30)

        feature_increment = dt.date(2018, 3, 1)
        snd_feature_usage_start = dt.date(2018, 3, 2)
        snd_feature_usage_end = dt.date(2018, 3, 30)

        ## Lots of test setup {{{

        provider = ProviderFactory.create(flow=Provider.FLOWS.INVOICE)

        customer = CustomerFactory.create(consolidated_billing=False,
                                          sales_tax_percent=Decimal('0.00'))
        currency = 'USD'

        plan = PlanFactory.create(
            interval=Plan.INTERVALS.YEAR,
            interval_count=1,
            generate_after=0,
            enabled=True,
            provider=provider,
            product_code=ProductCodeFactory(value="yearly-seat-plan"),
            amount=Decimal('10.00'),
            prebill_plan=False,
            currency=currency,
            trial_period_days=None,
            cycle_billing_duration=dt.timedelta(days=1),
        )
        plan.save()

        # Create the prorated subscription
        subscription = SubscriptionFactory.create(plan=plan,
                                                  start_date=start_date,
                                                  customer=customer)
        subscription.activate()
        subscription.save()

        ## }}}

        ## First test billing phase {{{
        call_command('generate_docs',
                     date=fst_feature_usage_start,
                     stdout=self.output)

        assert Invoice.objects.all().count() == 0

        # zomg time travel so l33t
        with freeze_time('2018-07-01') as T:
            subscription.cancel(when='now')
            subscription.save()

        call_command('generate_docs',
                     date=end_billing_date,
                     force_generate=True,
                     stdout=self.output)

        assert Invoice.objects.all().count() == 1
        print("  END OF YEAR  ")
        year_invoice = Invoice.objects.first()
        print_entries(year_invoice)

        # Final year total should be 10 for the whole base plan.
        assert Decimal(4.98) <= year_invoice.total <= Decimal(5.00)