forked from data.coop/membersystem
Compare commits
No commits in common. "17e5f969af4bb7e9e5062df92a56783cbc2642ed" and "4c810efe6c7709a67a737271f79fe49b2f764077" have entirely different histories.
17e5f969af
...
4c810efe6c
8
Makefile
8
Makefile
|
@ -1,4 +1,4 @@
|
||||||
.PHONY: run makemigrations migrate createsuperuser shell manage_command build requirements
|
.PHONY: run pre_commit_install pre_commit_run_all makemigrations migrate createsuperuser shell manage_command build requirements
|
||||||
DOCKER_COMPOSE = COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose
|
DOCKER_COMPOSE = COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose
|
||||||
DOCKER_RUN = ${DOCKER_COMPOSE} run -u `id -u`
|
DOCKER_RUN = ${DOCKER_COMPOSE} run -u `id -u`
|
||||||
MANAGE_EXEC = python /app/src/manage.py
|
MANAGE_EXEC = python /app/src/manage.py
|
||||||
|
@ -7,6 +7,12 @@ MANAGE_COMMAND = ${DOCKER_RUN} app ${MANAGE_EXEC}
|
||||||
run:
|
run:
|
||||||
${DOCKER_COMPOSE} up
|
${DOCKER_COMPOSE} up
|
||||||
|
|
||||||
|
pre_commit_install:
|
||||||
|
venv/bin/pre-commit install
|
||||||
|
|
||||||
|
pre_commit_run_all:
|
||||||
|
venv/bin/pre-commit run --all-files
|
||||||
|
|
||||||
makemigrations:
|
makemigrations:
|
||||||
${MANAGE_COMMAND} makemigrations ${ARGS}
|
${MANAGE_COMMAND} makemigrations ${ARGS}
|
||||||
|
|
||||||
|
|
10
README.md
10
README.md
|
@ -98,3 +98,13 @@ hatch-pip-compile
|
||||||
# Update requirements/requirements-dev.txt:
|
# Update requirements/requirements-dev.txt:
|
||||||
hatch-pip-compile dev
|
hatch-pip-compile dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Updating requirements
|
||||||
|
|
||||||
|
If you want to update the requirements, you can run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hatch run requirements
|
||||||
|
```
|
||||||
|
|
||||||
|
This uses [hatch-pip-compile](https://juftin.com/hatch-pip-compile/) to update the requirements.
|
||||||
|
|
|
@ -15,27 +15,23 @@ from django.db.models import QuerySet
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
||||||
from .models import Member
|
from . import models
|
||||||
from .models import Membership
|
|
||||||
from .models import MembershipType
|
|
||||||
from .models import SubscriptionPeriod
|
|
||||||
from .models import WaitingListEntry
|
|
||||||
|
|
||||||
# Do not use existing user admin
|
# Do not use existing user admin
|
||||||
admin.site.unregister(User)
|
admin.site.unregister(User)
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Membership)
|
@admin.register(models.Membership)
|
||||||
class MembershipAdmin(admin.ModelAdmin):
|
class MembershipAdmin(admin.ModelAdmin):
|
||||||
"""Admin for Membership model."""
|
"""Admin for Membership model."""
|
||||||
|
|
||||||
|
|
||||||
@admin.register(MembershipType)
|
@admin.register(models.MembershipType)
|
||||||
class MembershipTypeAdmin(admin.ModelAdmin):
|
class MembershipTypeAdmin(admin.ModelAdmin):
|
||||||
"""Admin for MembershipType model."""
|
"""Admin for MembershipType model."""
|
||||||
|
|
||||||
|
|
||||||
@admin.register(SubscriptionPeriod)
|
@admin.register(models.SubscriptionPeriod)
|
||||||
class SubscriptionPeriodAdmin(admin.ModelAdmin):
|
class SubscriptionPeriodAdmin(admin.ModelAdmin):
|
||||||
"""Admin for SubscriptionPeriod model."""
|
"""Admin for SubscriptionPeriod model."""
|
||||||
|
|
||||||
|
@ -43,10 +39,10 @@ class SubscriptionPeriodAdmin(admin.ModelAdmin):
|
||||||
class MembershipInlineAdmin(admin.TabularInline):
|
class MembershipInlineAdmin(admin.TabularInline):
|
||||||
"""Inline admin."""
|
"""Inline admin."""
|
||||||
|
|
||||||
model = Membership
|
model = models.Membership
|
||||||
|
|
||||||
|
|
||||||
def decorate_ensure_membership_type_exists(membership_type: MembershipType, label: str) -> Callable:
|
def decorate_ensure_membership_type_exists(membership_type: models.MembershipType, label: str) -> Callable:
|
||||||
"""Generate an admin action for given membership type and label."""
|
"""Generate an admin action for given membership type and label."""
|
||||||
|
|
||||||
@admin.action(description=label)
|
@admin.action(description=label)
|
||||||
|
@ -60,7 +56,7 @@ def decorate_ensure_membership_type_exists(membership_type: MembershipType, labe
|
||||||
def ensure_membership_type_exists(
|
def ensure_membership_type_exists(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
queryset: QuerySet,
|
queryset: QuerySet,
|
||||||
membership_type: MembershipType,
|
membership_type: models.MembershipType,
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
"""Inner function that ensures that a membership exists for a given queryset of Member objects."""
|
"""Inner function that ensures that a membership exists for a given queryset of Member objects."""
|
||||||
for member in queryset:
|
for member in queryset:
|
||||||
|
@ -75,10 +71,10 @@ def ensure_membership_type_exists(
|
||||||
for product in membership_type.products.all():
|
for product in membership_type.products.all():
|
||||||
OrderProduct.objects.create(order=order, product=product, price=product.price, vat=product.vat)
|
OrderProduct.objects.create(order=order, product=product, price=product.price, vat=product.vat)
|
||||||
# Create the Membership
|
# Create the Membership
|
||||||
Membership.objects.create(
|
models.Membership.objects.create(
|
||||||
membership_type=membership_type,
|
membership_type=membership_type,
|
||||||
user=member,
|
user=member,
|
||||||
period=SubscriptionPeriod.objects.current(),
|
period=models.SubscriptionPeriod.objects.current(),
|
||||||
order=order,
|
order=order,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -86,7 +82,7 @@ def ensure_membership_type_exists(
|
||||||
messages.success(request, f"{member} has ordered a '{membership_type}' (unpaid)")
|
messages.success(request, f"{member} has ordered a '{membership_type}' (unpaid)")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Member)
|
@admin.register(models.Member)
|
||||||
class MemberAdmin(UserAdmin):
|
class MemberAdmin(UserAdmin):
|
||||||
"""Member admin is actually an admin for User objects."""
|
"""Member admin is actually an admin for User objects."""
|
||||||
|
|
||||||
|
@ -95,12 +91,12 @@ class MemberAdmin(UserAdmin):
|
||||||
|
|
||||||
def get_actions(self, request: HttpRequest) -> dict:
|
def get_actions(self, request: HttpRequest) -> dict:
|
||||||
"""Populate actions with dynamic data (MembershipType)."""
|
"""Populate actions with dynamic data (MembershipType)."""
|
||||||
current_period = SubscriptionPeriod.objects.current()
|
current_period = models.SubscriptionPeriod.objects.current()
|
||||||
|
|
||||||
super_dict = super().get_actions(request)
|
super_dict = super().get_actions(request)
|
||||||
|
|
||||||
if current_period:
|
if current_period:
|
||||||
for i, mtype in enumerate(MembershipType.objects.filter(active=True)):
|
for i, mtype in enumerate(models.MembershipType.objects.filter(active=True)):
|
||||||
action_label = f"Ensure membership {mtype.name}, {current_period.period}, {mtype.total_including_vat}"
|
action_label = f"Ensure membership {mtype.name}, {current_period.period}, {mtype.total_including_vat}"
|
||||||
action_func = decorate_ensure_membership_type_exists(mtype, action_label)
|
action_func = decorate_ensure_membership_type_exists(mtype, action_label)
|
||||||
# Django ModelAdmin uses the non-unique __name__ property, so we need to suffix it to make it unique
|
# Django ModelAdmin uses the non-unique __name__ property, so we need to suffix it to make it unique
|
||||||
|
@ -110,6 +106,6 @@ class MemberAdmin(UserAdmin):
|
||||||
return super_dict
|
return super_dict
|
||||||
|
|
||||||
|
|
||||||
@admin.register(WaitingListEntry)
|
@admin.register(models.WaitingListEntry)
|
||||||
class WaitingListEntryAdmin(admin.ModelAdmin):
|
class WaitingListEntryAdmin(admin.ModelAdmin):
|
||||||
"""Admin for WaitingList model."""
|
"""Admin for WaitingList model."""
|
||||||
|
|
Loading…
Reference in a new issue