-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6abb9ef
commit d9db172
Showing
16 changed files
with
349 additions
and
0 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
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,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class LendingConfig(AppConfig): | ||
name = "lego.apps.lending" | ||
verbose_name = "Lending" |
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,20 @@ | ||
from django_filters.rest_framework import FilterSet | ||
|
||
from lego.apps.lending.models import LendableObject, LendingInstance | ||
|
||
|
||
class LendableObjectFilterSet(FilterSet): | ||
class Meta: | ||
model = LendableObject | ||
fields = ["title"] | ||
|
||
|
||
class LendingInstanceFilterSet(FilterSet): | ||
class Meta: | ||
model = LendingInstance | ||
fields = [ | ||
"user", | ||
"lendable_object", | ||
"start_date", | ||
"pending", | ||
] |
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,25 @@ | ||
from lego.utils.managers import PersistentModelManager | ||
|
||
|
||
class LendingInstanceManager(PersistentModelManager): | ||
def create(self, *args, **kwargs): | ||
from lego.apps.users.models import Membership, User | ||
from lego.apps.lending.notifications import LendingInstanceNotification | ||
|
||
lending_instance = super().create(*args, **kwargs) | ||
abakus_groups = lending_instance.lendable_object.responsible_groups.all() | ||
role = lending_instance.lendable_object.responsible_role | ||
|
||
users_to_be_notified = Membership.objects.filter( | ||
abakus_group__in=abakus_groups, role=role | ||
).values_list("user", flat=True) | ||
|
||
for user_id in users_to_be_notified: | ||
user = User.objects.get(pk=user_id) | ||
notification = LendingInstanceNotification( | ||
lending_instance=lending_instance, | ||
user_email=user, | ||
) | ||
notification.notify() | ||
|
||
return lending_instance |
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,60 @@ | ||
# Generated by Django 4.0.10 on 2023-10-04 19:54 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import django.utils.timezone | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('users', '0041_user_linkedin_id_alter_user_github_username'), | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='LendableObject', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now, editable=False)), | ||
('updated_at', models.DateTimeField(default=django.utils.timezone.now, editable=False)), | ||
('deleted', models.BooleanField(db_index=True, default=False, editable=False)), | ||
('title', models.CharField(max_length=128)), | ||
('description', models.TextField(blank=True)), | ||
('has_contract', models.BooleanField(default=False)), | ||
('max_lending_period', models.DurationField(null=True)), | ||
('responsible_role', models.CharField(choices=[('member', 'member'), ('leader', 'leader'), ('co-leader', 'co-leader'), ('treasurer', 'treasurer'), ('recruiting', 'recruiting'), ('development', 'development'), ('editor', 'editor'), ('retiree', 'retiree'), ('media_relations', 'media_relations'), ('active_retiree', 'active_retiree'), ('alumni', 'alumni'), ('webmaster', 'webmaster'), ('interest_group_admin', 'interest_group_admin'), ('alumni_admin', 'alumni_admin'), ('retiree_email', 'retiree_email'), ('company_admin', 'company_admin'), ('dugnad_admin', 'dugnad_admin'), ('trip_admin', 'trip_admin'), ('sponsor_admin', 'sponsor_admin'), ('social_admin', 'social_admin')], default='member', max_length=30)), | ||
('created_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created', to=settings.AUTH_USER_MODEL)), | ||
('responsible_groups', models.ManyToManyField(to='users.abakusgroup')), | ||
('updated_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_updated', to=settings.AUTH_USER_MODEL)), | ||
], | ||
options={ | ||
'abstract': False, | ||
'default_manager_name': 'objects', | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name='LendingInstance', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now, editable=False)), | ||
('updated_at', models.DateTimeField(default=django.utils.timezone.now, editable=False)), | ||
('deleted', models.BooleanField(db_index=True, default=False, editable=False)), | ||
('start_date', models.DateTimeField(null=True)), | ||
('end_date', models.DateTimeField(null=True)), | ||
('pending', models.BooleanField(default=True)), | ||
('created_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created', to=settings.AUTH_USER_MODEL)), | ||
('lendable_object', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lending.lendableobject')), | ||
('updated_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_updated', to=settings.AUTH_USER_MODEL)), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||
], | ||
options={ | ||
'abstract': False, | ||
'default_manager_name': 'objects', | ||
}, | ||
), | ||
] |
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,42 @@ | ||
from datetime import datetime, timedelta, timezone, tzinfo | ||
|
||
from django.db import models | ||
|
||
from lego.apps.users import constants | ||
from lego.apps.lending.managers import LendingInstanceManager | ||
|
||
|
||
from lego.utils.models import BasisModel | ||
|
||
|
||
# Create your models here. | ||
|
||
|
||
class LendableObject(BasisModel): | ||
title = models.CharField(max_length=128, null=False, blank=False) | ||
description = models.TextField(null=False, blank=True) | ||
has_contract = models.BooleanField(default=False, null=False, blank=False) | ||
max_lending_period = models.DurationField(null=True, blank=False) | ||
responsible_groups = models.ManyToManyField("users.AbakusGroup") | ||
responsible_role = models.CharField( | ||
max_length=30, choices=constants.ROLES, default=constants.MEMBER | ||
) | ||
location = models.CharField(max_length=128, null=False, blank=False) | ||
|
||
@property | ||
def get_furthest_booking_date(self): | ||
return timezone.now() + timedelta(days=14) | ||
|
||
|
||
class LendingInstance(BasisModel): | ||
user = models.ForeignKey("users.User", on_delete=models.CASCADE) | ||
lendable_object = models.ForeignKey(LendableObject, on_delete=models.CASCADE) | ||
start_date = models.DateTimeField(null=True) | ||
end_date = models.DateTimeField(null=True) | ||
pending = models.BooleanField(default=True) | ||
|
||
objects = LendingInstanceManager() # type: ignore | ||
|
||
@property | ||
def active(self): | ||
return timezone.now() < self.end_date and timezone.now() > self.start_date |
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,40 @@ | ||
from lego.apps.lending.models import LendingInstance | ||
from lego.apps.notifications.notification import Notification | ||
from lego.apps.users.models import User | ||
|
||
|
||
class LendingInstanceNotification(Notification): | ||
def __init__(self, lending_instance: LendingInstance, user: User): | ||
self.lending_instance = lending_instance | ||
self.user = user | ||
|
||
# TODO: Might not work | ||
super().__init__(user=lending_instance.user) | ||
|
||
name = "lending_instance_creation" | ||
|
||
def generate_mail(self): | ||
return self._delay_mail( | ||
to_email=self.user.email_address, | ||
context={ | ||
"user": self.user.full_name, | ||
"lendable_object": self.lending_instance.lendable_object.title, | ||
"start_date": self.lending_instance.start_date, | ||
"end_date": self.lending_instance.end_date, | ||
}, | ||
subject="Utlån forespørsel", | ||
plain_template="users/email/lending_instance.txt", | ||
html_template="users/email/lending_instance.html", | ||
) | ||
|
||
def generate_push(self): | ||
return self._delay_push( | ||
template="users/push/lending_instance.txt", | ||
context={ | ||
"user": self.user.full_name, | ||
"lendable_object": self.lending_instance.lendable_object.title, | ||
"start_date": self.lending_instance.start_date, | ||
"end_date": self.lending_instance.end_date, | ||
}, | ||
instance=self.lending_instance, | ||
) |
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,37 @@ | ||
from rest_framework import serializers | ||
|
||
|
||
from lego.apps.lending.models import LendableObject, LendingInstance | ||
|
||
|
||
class LendableObjectSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = LendableObject | ||
fields = "__all__" | ||
|
||
|
||
class LendingInstanceSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = LendingInstance | ||
fields = "__all__" | ||
|
||
def validate(self, data): | ||
lendable_object_id = data["lendable_object"].id | ||
lendable_object = LendableObject.objects.get(id=lendable_object_id) | ||
user = self.request.user | ||
|
||
if not user.abakus_groups.filter( | ||
id__in=lendable_object.responsible_groups.all().values_list("id", flat=True) | ||
).exists(): | ||
if ( | ||
data["end_date"] - data["start_date"] | ||
> lendable_object.max_lending_period | ||
): | ||
raise serializers.ValidationError( | ||
"Lending period exceeds maximum allowed duration" | ||
) | ||
|
||
# Add additional validation logic as per your use case | ||
# ... | ||
|
||
return data |
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,3 @@ | ||
from django.test import TestCase | ||
|
||
# Create your tests here. |
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,60 @@ | ||
from rest_framework import ( | ||
decorators, | ||
exceptions, | ||
mixins, | ||
permissions, | ||
renderers, | ||
status, | ||
viewsets, | ||
) | ||
from rest_framework.response import Response | ||
from rest_framework.viewsets import GenericViewSet | ||
|
||
from lego.apps.lending.filters import LendableObjectFilterSet, LendingInstanceFilterSet | ||
from lego.apps.lending.models import LendableObject, LendingInstance | ||
from lego.apps.lending.serializers import ( | ||
LendableObjectSerializer, | ||
LendingInstanceSerializer, | ||
) | ||
from lego.apps.permissions.api.views import AllowedPermissionsMixin | ||
|
||
|
||
class LendableObjectViewSet( | ||
AllowedPermissionsMixin, | ||
mixins.CreateModelMixin, | ||
mixins.DestroyModelMixin, | ||
mixins.ListModelMixin, | ||
GenericViewSet, | ||
): | ||
queryset = LendableObject.objects.all() | ||
serializer_class = LendableObjectSerializer | ||
filterset_class = LendableObjectFilterSet | ||
http_method_names = ["get", "post", "patch", "delete", "head", "options"] | ||
permission_classes = [ | ||
permissions.IsAuthenticated, | ||
] | ||
|
||
|
||
class LendingInstanceViewSet( | ||
AllowedPermissionsMixin, | ||
mixins.CreateModelMixin, | ||
mixins.DestroyModelMixin, | ||
mixins.ListModelMixin, | ||
GenericViewSet, | ||
): | ||
queryset = LendingInstance.objects.all() | ||
serializer_class = LendingInstanceSerializer | ||
filterset_class = LendingInstanceFilterSet | ||
http_method_names = ["get", "post", "patch", "delete", "head", "options"] | ||
permission_classes = [ | ||
permissions.IsAuthenticated, | ||
] | ||
|
||
def create(self, request): | ||
serializer = LendingInstanceSerializer(request, data=request.data) | ||
|
||
if serializer.is_valid(raise_exception=True): | ||
serializer.save() | ||
return Response(data=serializer.data, status=status.HTTP_201_CREATED) | ||
|
||
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
31 changes: 31 additions & 0 deletions
31
lego/apps/users/templates/users/email/lending_instance.html
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,31 @@ | ||
{% extends "email/base.html" %} | ||
|
||
{% block alert %} | ||
|
||
<tr> | ||
<td class="alert alert-warning"> | ||
Det er en ny forespørsel om å låne {{ lendable_object }}! | ||
</td> | ||
</tr> | ||
|
||
{% endblock %} | ||
|
||
{% block content %} | ||
|
||
<tr> | ||
<td class="content-block"> | ||
Bruker: {{ user }}! | ||
</td> | ||
</tr> | ||
|
||
|
||
|
||
<tr> | ||
<td class="content-block"> | ||
<i>Fra: {{ start_date }}, Til: {{ end_date }} </i> | ||
</td> | ||
</tr> | ||
|
||
|
||
|
||
{% endblock %} |
14 changes: 14 additions & 0 deletions
14
lego/apps/users/templates/users/email/lending_instance.txt
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,14 @@ | ||
{% extends "email/base.txt" %} | ||
|
||
{% block content %} | ||
|
||
Det er en ny forespørsel om å låne {{ lendable_object }}! | ||
|
||
Bruker: {{ user }}! | ||
|
||
Fra: {{ start_date }}, Til: {{ end_date }} | ||
|
||
|
||
|
||
|
||
{% endblock %} |
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,5 @@ | ||
Det er en ny forespørsel om å låne {{ lendable_object }}! | ||
|
||
Bruker: {{ user }}! | ||
|
||
Fra: {{ start_date }}, Til: {{ end_date }} |
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