Refactoring things and doing stuff in a MVP way. #15
|
@ -18,4 +18,3 @@ if [ -z "$DEBUG" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Generated by Django 3.1.7 on 2021-02-27 20:06
|
# Generated by Django 3.1.7 on 2021-02-27 20:06
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import djmoney.models.fields
|
import djmoney.models.fields
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -16,67 +16,221 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Account',
|
name="Account",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"owner",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
"abstract": False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Order',
|
name="Order",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('description', models.CharField(max_length=1024, verbose_name='description')),
|
auto_created=True,
|
||||||
('price_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)),
|
primary_key=True,
|
||||||
('price', djmoney.models.fields.MoneyField(decimal_places=2, max_digits=16, verbose_name='price (excl. VAT)')),
|
serialize=False,
|
||||||
('vat_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)),
|
verbose_name="ID",
|
||||||
('vat', djmoney.models.fields.MoneyField(decimal_places=2, max_digits=16, verbose_name='VAT')),
|
),
|
||||||
('is_paid', models.BooleanField(default=False, verbose_name='is paid')),
|
),
|
||||||
('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='accounting.account')),
|
(
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"description",
|
||||||
|
models.CharField(max_length=1024, verbose_name="description"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"price_currency",
|
||||||
|
djmoney.models.fields.CurrencyField(
|
||||||
|
choices=[("DKK", "DKK")],
|
||||||
|
default="XYZ",
|
||||||
|
editable=False,
|
||||||
|
max_length=3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"price",
|
||||||
|
djmoney.models.fields.MoneyField(
|
||||||
|
decimal_places=2,
|
||||||
|
max_digits=16,
|
||||||
|
verbose_name="price (excl. VAT)",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"vat_currency",
|
||||||
|
djmoney.models.fields.CurrencyField(
|
||||||
|
choices=[("DKK", "DKK")],
|
||||||
|
default="XYZ",
|
||||||
|
editable=False,
|
||||||
|
max_length=3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"vat",
|
||||||
|
djmoney.models.fields.MoneyField(
|
||||||
|
decimal_places=2, max_digits=16, verbose_name="VAT"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("is_paid", models.BooleanField(default=False, verbose_name="is paid")),
|
||||||
|
(
|
||||||
|
"account",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="accounting.account",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'Order',
|
"verbose_name": "Order",
|
||||||
'verbose_name_plural': 'Orders',
|
"verbose_name_plural": "Orders",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Transaction',
|
name="Transaction",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('amount_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)),
|
auto_created=True,
|
||||||
('amount', djmoney.models.fields.MoneyField(decimal_places=2, help_text='This will include VAT', max_digits=16, verbose_name='amount')),
|
primary_key=True,
|
||||||
('description', models.CharField(max_length=1024, verbose_name='description')),
|
serialize=False,
|
||||||
('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transactions', to='accounting.account')),
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"amount_currency",
|
||||||
|
djmoney.models.fields.CurrencyField(
|
||||||
|
choices=[("DKK", "DKK")],
|
||||||
|
default="XYZ",
|
||||||
|
editable=False,
|
||||||
|
max_length=3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"amount",
|
||||||
|
djmoney.models.fields.MoneyField(
|
||||||
|
decimal_places=2,
|
||||||
|
help_text="This will include VAT",
|
||||||
|
max_digits=16,
|
||||||
|
verbose_name="amount",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"description",
|
||||||
|
models.CharField(max_length=1024, verbose_name="description"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"account",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="transactions",
|
||||||
|
to="accounting.account",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
"abstract": False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Payment',
|
name="Payment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('amount_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)),
|
auto_created=True,
|
||||||
('amount', djmoney.models.fields.MoneyField(decimal_places=2, max_digits=16)),
|
primary_key=True,
|
||||||
('description', models.CharField(max_length=1024, verbose_name='description')),
|
serialize=False,
|
||||||
('stripe_charge_id', models.CharField(blank=True, max_length=255, null=True)),
|
verbose_name="ID",
|
||||||
('order', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='accounting.order')),
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"amount_currency",
|
||||||
|
djmoney.models.fields.CurrencyField(
|
||||||
|
choices=[("DKK", "DKK")],
|
||||||
|
default="XYZ",
|
||||||
|
editable=False,
|
||||||
|
max_length=3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"amount",
|
||||||
|
djmoney.models.fields.MoneyField(decimal_places=2, max_digits=16),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"description",
|
||||||
|
models.CharField(max_length=1024, verbose_name="description"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"stripe_charge_id",
|
||||||
|
models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"order",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="accounting.order",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'payment',
|
"verbose_name": "payment",
|
||||||
'verbose_name_plural': 'payments',
|
"verbose_name_plural": "payments",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import Membership, MembershipType
|
from .models import Membership
|
||||||
|
from .models import MembershipType
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Membership)
|
@admin.register(Membership)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# Generated by Django 3.1.7 on 2021-02-28 21:09
|
# Generated by Django 3.1.7 on 2021-02-28 21:09
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
import django.contrib.postgres.fields.ranges
|
import django.contrib.postgres.fields.ranges
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -16,31 +16,78 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='MembershipType',
|
name="MembershipType",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('name', models.CharField(max_length=64, verbose_name='navn')),
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=64, verbose_name="navn")),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'membership type',
|
"verbose_name": "membership type",
|
||||||
'verbose_name_plural': 'membership types',
|
"verbose_name_plural": "membership types",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Membership',
|
name="Membership",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('modified', models.DateTimeField(auto_now=True, verbose_name='modified')),
|
"id",
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='oprettet')),
|
models.AutoField(
|
||||||
('period', django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='The duration this subscription is for. ')),
|
auto_created=True,
|
||||||
('membership_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='memberships', to='membership.membershiptype', verbose_name='subscription type')),
|
primary_key=True,
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
models.DateTimeField(auto_now=True, verbose_name="modified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
models.DateTimeField(auto_now_add=True, verbose_name="oprettet"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"period",
|
||||||
|
django.contrib.postgres.fields.ranges.DateTimeRangeField(
|
||||||
|
help_text="The duration this subscription is for. "
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"membership_type",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="memberships",
|
||||||
|
to="membership.membershiptype",
|
||||||
|
verbose_name="subscription type",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'membership',
|
"verbose_name": "membership",
|
||||||
'verbose_name_plural': 'memberships',
|
"verbose_name_plural": "memberships",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -15,14 +15,12 @@ class CreatedModifiedAbstract(models.Model):
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Membership(CreatedModifiedAbstract):
|
class Membership(CreatedModifiedAbstract):
|
||||||
"""
|
"""
|
||||||
Tracks that a user has membership of a given type for a given period.
|
Tracks that a user has membership of a given type for a given period.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class QuerySet(models.QuerySet):
|
class QuerySet(models.QuerySet):
|
||||||
|
|
||||||
def for_user(self, user):
|
def for_user(self, user):
|
||||||
return self.filter(user=user)
|
return self.filter(user=user)
|
||||||
|
|
||||||
|
@ -76,6 +74,3 @@ class MembershipType(CreatedModifiedAbstract):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from environs import Env
|
from environs import Env
|
||||||
|
|
||||||
env = Env()
|
env = Env()
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
"""URLs for the membersystem"""
|
"""URLs for the membersystem"""
|
||||||
|
import debug_toolbar
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.urls import include
|
from django.urls import include
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
import debug_toolbar
|
|
||||||
|
|
||||||
from .views import index, services_overview
|
|
||||||
from membership.views import membership_overview
|
from membership.views import membership_overview
|
||||||
|
|
||||||
|
from .views import index
|
||||||
|
from .views import services_overview
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", login_required(index), name="index"),
|
path("", login_required(index), name="index"),
|
||||||
path("services/", login_required(services_overview), name="services-overview"),
|
path("services/", login_required(services_overview), name="services-overview"),
|
||||||
path("membership/", membership_overview, name="membership-overview"),
|
path("membership/", membership_overview, name="membership-overview"),
|
||||||
path('accounts/', include('allauth.urls')),
|
path("accounts/", include("allauth.urls")),
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("__debug__/", include(debug_toolbar.urls)),
|
path("__debug__/", include(debug_toolbar.urls)),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue