Repository: dj-stripe/dj-stripe

Issue:
Subscription.start is updated when subscription is canceled
When I cancel a subscription, Subscription.start is also updated to the date when the subscription was canceled. I haven't investigated deeper but this behaviour looks wrong. According to the code, Subscription.start is the "date the subscription started". 

https://github.com/dj-stripe/dj-stripe/blob/4490fda09e5888da82499f1e17ecf883b00b36c6/djstripe/models/billing.py#L963

Here is the trace of the commands I ran

```
>>> su = Subscription.objects.last()
>>> su.cancel_at_period_end
False
>>> su.start
datetime.datetime(2019, 3, 6, 14, 47, 51, tzinfo=<UTC>)
>>> su.current_period_start
datetime.datetime(2019, 3, 6, 14, 47, 51, tzinfo=<UTC>)
>>> su.current_period_end
datetime.datetime(2019, 3, 31, 22, 0, tzinfo=<UTC>)

>>> su.cancel()
<Subscription: *****@*****.*** on  **************>

>>> su = Subscription.objects.last()
>>> su.cancel_at_period_end
True
>>> su.start
datetime.datetime(2019, 3, 6, 15, 44, 29, tzinfo=<UTC>)
>>> su.current_period_start
datetime.datetime(2019, 3, 6, 14, 47, 51, tzinfo=<UTC>)
>>> 
>>> su.current_period_end
datetime.datetime(2019, 3, 31, 22, 0, tzinfo=<UTC>)
>>> su.canceled_at
datetime.datetime(2019, 3, 6, 15, 44, 29, tzinfo=<UTC>)
```


Discussion:
I noticed the same thing, according to [stripe's documentation ](https://stripe.com/docs/api/subscriptions/object#subscription_object-start) for the subscription object, the `start` attribute is the `date of the last substantial change to this subscription` (the name is misleading). The method `is_status_temporarily_current` on the `Subscription` model will always return `False` because `self.start` will always equal `self.cancelled_at`.

Maybe something like this could work ?
```python
def is_status_temporarily_current(self):
    return (self.canceled_at and self.cancel_at_period_end and datetime.utcnow().replace(tzinfo=utc) < self.current_period_end)
```

Resolving patch:
diff --git a/djstripe/migrations/0001_initial.py b/djstripe/migrations/0001_initial.py
--- a/djstripe/migrations/0001_initial.py
+++ b/djstripe/migrations/0001_initial.py
@@ -2457,7 +2457,7 @@ class Migration(migrations.Migration):
                 (
                     "start",
                     djstripe.fields.StripeDateTimeField(
-                        help_text="Date the subscription started."
+                        help_text="Date of the last substantial change to this subscription. For example, a change to the items array, or a change of status, will reset this timestamp."
                     ),
                 ),
                 (
diff --git a/djstripe/models/billing.py b/djstripe/models/billing.py
--- a/djstripe/models/billing.py
+++ b/djstripe/models/billing.py
@@ -1072,7 +1072,11 @@ class Subscription(StripeModel):
         help_text="The quantity applied to this subscription. This value will be "
         "`null` for multi-plan subscriptions",
     )
-    start = StripeDateTimeField(help_text="Date the subscription started.")
+    start = StripeDateTimeField(
+        help_text="Date of the last substantial change to "
+        "this subscription. For example, a change to the items array, or a change "
+        "of status, will reset this timestamp."
+    )
     status = StripeEnumField(
         enum=enums.SubscriptionStatus, help_text="The status of this subscription."
     )
@@ -1295,8 +1299,8 @@ def is_status_temporarily_current(self):
 
         return (
             self.canceled_at
-            and self.start < self.canceled_at
             and self.cancel_at_period_end
+            and timezone.now() < self.current_period_end
         )
 
     def is_valid(self):


Test patch:
diff --git a/tests/test_subscription.py b/tests/test_subscription.py
--- a/tests/test_subscription.py
+++ b/tests/test_subscription.py
@@ -391,6 +391,7 @@ def test_cancel_now(
         self.assertEqual(False, new_subscription.cancel_at_period_end)
         self.assertEqual(new_subscription.canceled_at, new_subscription.ended_at)
         self.assertFalse(new_subscription.is_valid())
+        self.assertFalse(new_subscription.is_status_temporarily_current())
         self.assertFalse(new_subscription in self.customer.active_subscriptions)
         self.assertFalse(self.customer.has_active_subscription())
         self.assertFalse(self.customer.has_any_active_subscription())
@@ -436,6 +437,7 @@ def test_cancel_at_period_end(
         self.assertTrue(subscription in self.customer.active_subscriptions)
 
         new_subscription = subscription.cancel(at_period_end=True)
+
         self.assertEqual(self.customer.active_subscriptions.count(), 1)
         self.assertTrue(new_subscription in self.customer.active_subscriptions)
 
@@ -443,6 +445,7 @@ def test_cancel_at_period_end(
         self.assertEqual(True, new_subscription.cancel_at_period_end)
         self.assertNotEqual(new_subscription.canceled_at, new_subscription.ended_at)
         self.assertTrue(new_subscription.is_valid())
+        self.assertTrue(new_subscription.is_status_temporarily_current())
         self.assertTrue(self.customer.has_active_subscription())
         self.assertTrue(self.customer.has_any_active_subscription())