Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding base project and barebone models structures
- Loading branch information
1 parent
2018cff
commit a78b546
Showing
23 changed files
with
321 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,6 @@ Contents: | |
installation | ||
usage | ||
code | ||
documentation/modules | ||
contributing | ||
authors | ||
history |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
__version__ = '0.1.0' | ||
default_app_config = 'flexible_plans.apps.FlexiblePlansConfig' |
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from django.core.exceptions import ObjectDoesNotExist | ||
from django.urls import reverse | ||
|
||
|
||
def subscription_status(request): | ||
""" | ||
User Subscription Context Processor, to keep the Subscription Status available in the templates | ||
* ``ACCOUNT_EXPIRED = boolean``, account was expired state, | ||
* ``ACCOUNT_NOT_ACTIVE = boolean``, set when account is not expired, but it is over quotas so it is | ||
not active | ||
* ``EXPIRE_IN_DAYS = integer``, number of days to account expiration, | ||
* ``EXTEND_URL = string``, URL to account extend page. | ||
* ``ACTIVATE_URL = string``, URL to account activation needed if account is not active | ||
:param request: HttpRequest object | ||
:return: the current user susbscription status object | ||
""" | ||
if request.user.is_authenticated: | ||
try: | ||
return { | ||
'ACCOUNT_EXPIRED': request.user.subscription.is_expired(), | ||
'ACCOUNT_NOT_ACTIVE': ( | ||
not request.user.subscription.is_active() and not request.user.subscription.is_expired()), | ||
'EXPIRE_IN_DAYS': request.user.subscription.days_left(), | ||
'EXTEND_URL': reverse('current_plan'), | ||
'ACTIVATE_URL': reverse('account_activation'), | ||
} | ||
except ObjectDoesNotExist: | ||
pass | ||
return {} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from django.core.management import BaseCommand | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
import_plans Management Command | ||
Usage: from the project shell invoke the admin command | ||
.. code-block:: bash | ||
$ python manage.py import_plans <provider_name> | ||
where <provider_name> must match with the providers' name configured in settings (all lowercase) | ||
""" | ||
help = '' | ||
|
||
def handle(self, *args, **options): | ||
pass | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Generated by Django 2.1.5 on 2019-01-28 14:58 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import django.utils.timezone | ||
import model_utils.fields | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('auth', '0009_alter_user_last_name_max_length'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Feature', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=255, verbose_name='name')), | ||
('codename', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='codename')), | ||
], | ||
options={ | ||
'swappable': 'FLEXIBLE_PLANS_FEATURE_MODEL', | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name='Plan', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), | ||
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), | ||
('is_removed', models.BooleanField(default=False)), | ||
('name', models.CharField(max_length=255, unique=True, verbose_name='name')), | ||
('description', models.TextField(blank=True, verbose_name='description')), | ||
('default', models.NullBooleanField(db_index=True, default=None, help_text='Both "Unknown" and "No" means that the plan is not default', unique=True)), | ||
('available', models.BooleanField(db_index=True, default=False, help_text='Is still available for purchase', verbose_name='available')), | ||
('provider', models.CharField(max_length=100)), | ||
], | ||
options={ | ||
'swappable': 'FLEXIBLE_PLANS_PLAN_MODEL', | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name='CumulativeFeature', | ||
fields=[ | ||
('feature_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.FLEXIBLE_PLANS_FEATURE_MODEL)), | ||
('usage', models.PositiveIntegerField(default=0)), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
bases=('flexible_plans.feature',), | ||
), | ||
migrations.CreateModel( | ||
name='MeteredFeature', | ||
fields=[ | ||
('feature_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.FLEXIBLE_PLANS_FEATURE_MODEL)), | ||
('units', models.PositiveIntegerField(default=0)), | ||
('usage', models.PositiveIntegerField(default=0)), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
bases=('flexible_plans.feature',), | ||
), | ||
migrations.CreateModel( | ||
name='PermissionFeature', | ||
fields=[ | ||
('feature_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.FLEXIBLE_PLANS_FEATURE_MODEL)), | ||
('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='auth.Permission')), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
bases=('flexible_plans.feature',), | ||
), | ||
migrations.AddField( | ||
model_name='plan', | ||
name='features', | ||
field=models.ManyToManyField(to=settings.FLEXIBLE_PLANS_FEATURE_MODEL), | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__all__ = ['features', 'plans'] | ||
__all__ = ['features', 'plans', 'customers', 'subscriptions'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from django.db import models | ||
from django.conf import settings | ||
import swapper | ||
|
||
|
||
class Customer(models.Model): | ||
user = models.OneToOneField(settings.AUTH_USER, on_delete=models.CASCADE) | ||
|
||
class Meta: | ||
# Setting model as swappable | ||
swappable = swapper.swappable_setting('flexible_plans', 'Customer') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import swapper | ||
from django.db import models | ||
from model_utils.models import TimeStampedModel | ||
from datetime import date, timedelta, datetime | ||
|
||
|
||
class BaseSubscription(TimeStampedModel): | ||
""" | ||
Base class for user subscriptions to plans | ||
""" | ||
plan = models.ForeignKey(swapper.get_model_name('flexible_plans', 'Plan')) | ||
customer = models.ForeignKey(swapper.get_model_name('flexible_plans', 'Customer')) | ||
|
||
expire = models.DateField( | ||
_('expire'), default=None, blank=True, null=True, db_index=True) | ||
active = models.BooleanField(_('active'), default=True, db_index=True) | ||
|
||
def is_active(self): | ||
return self.active | ||
|
||
def is_expired(self): | ||
if self.expire is None: | ||
return False | ||
else: | ||
return self.expire < date.today() | ||
|
||
def days_left(self): | ||
if self.expire is None: | ||
return None | ||
else: | ||
return (self.expire - date.today()).days | ||
|
||
def clean_activation(self): | ||
errors = plan_validation(self.user) | ||
if not errors['required_to_activate']: | ||
plan_validation(self.user, on_activation=True) | ||
self.activate() | ||
else: | ||
self.deactivate() | ||
return errors | ||
|
||
class Meta: | ||
abstract = True | ||
|
||
|
||
class Subscription(BaseSubscription): | ||
""" | ||
Concrete swappable class for user subscriptions to plans | ||
""" | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
|
||
class PlanChangePolicy(object): | ||
""" | ||
Base Class to handle the plan change policies | ||
""" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from django.dispatch import Signal | ||
|
||
""" | ||
Signals to emit to coordinate with other applications depending on flexible_plans | ||
""" | ||
|
||
customer_created = Signal() | ||
customer_created.__doc__ = """ | ||
Sent after the creation of the Customer associated to the User | ||
""" | ||
|
||
|
Oops, something went wrong.