forked from DGNum/gestiojeux
Add minimal loans system
Functional loans system for users. No manager interface yet. See: - app "loans" - a few new views/templates in app "inventory"
This commit is contained in:
parent
a552e6d63b
commit
474083dd38
19 changed files with 318 additions and 2 deletions
0
loans/__init__.py
Normal file
0
loans/__init__.py
Normal file
6
loans/admin.py
Normal file
6
loans/admin.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
class LoanAdmin(admin.ModelAdmin):
|
||||
list_display = ("lent_object", "borrow_date", "return_date")
|
||||
ordering = ("-borrow_date",)
|
||||
list_filter = ("return_date", "borrow_date")
|
6
loans/apps.py
Normal file
6
loans/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LoansConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'loans'
|
4
loans/forms.py
Normal file
4
loans/forms.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
from django import forms
|
||||
|
||||
class BorrowForm(forms.Form):
|
||||
mail = forms.EmailField(label="Mail")
|
33
loans/migrations/0001_initial.py
Normal file
33
loans/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.8 on 2024-04-23 16:45
|
||||
|
||||
import autoslug.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0002_duration_range'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Loan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='game', unique=True)),
|
||||
('borrow_date', models.DateTimeField(auto_now_add=True)),
|
||||
('return_date', models.DateTimeField(null=True)),
|
||||
('mail', models.EmailField(max_length=254)),
|
||||
('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='loans', to='inventory.game', verbose_name='jeu emprunté')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'emprunt',
|
||||
'verbose_name_plural': 'emprunts',
|
||||
'ordering': ['borrow_date'],
|
||||
},
|
||||
),
|
||||
]
|
32
loans/migrations/0002_abstractloan_delete_loan.py
Normal file
32
loans/migrations/0002_abstractloan_delete_loan.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Generated by Django 4.2.8 on 2024-04-30 15:24
|
||||
|
||||
import autoslug.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('loans', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AbstractLoan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='game', unique=True)),
|
||||
('borrow_date', models.DateTimeField(auto_now_add=True)),
|
||||
('return_date', models.DateTimeField(null=True)),
|
||||
('mail', models.EmailField(max_length=254)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'emprunt',
|
||||
'verbose_name_plural': 'emprunts',
|
||||
'ordering': ['borrow_date'],
|
||||
},
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Loan',
|
||||
),
|
||||
]
|
0
loans/migrations/__init__.py
Normal file
0
loans/migrations/__init__.py
Normal file
32
loans/models.py
Normal file
32
loans/models.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from django.db import models
|
||||
from autoslug import AutoSlugField
|
||||
from django.utils.timezone import now
|
||||
|
||||
class AbstractLoan(models.Model):
|
||||
lent_object = None # Fill this with a foreign key in subclasses
|
||||
slug = AutoSlugField(unique=True, populate_from="lent_object")
|
||||
borrow_date = models.DateTimeField(auto_now_add=True)
|
||||
return_date = models.DateTimeField(null=True)
|
||||
mail = models.EmailField()
|
||||
|
||||
lent_object_slug_field = "slug"
|
||||
|
||||
class Meta:
|
||||
ordering=["borrow_date"]
|
||||
verbose_name = "emprunt"
|
||||
verbose_name_plural = "emprunts"
|
||||
|
||||
def __str__(self):
|
||||
return self.slug
|
||||
|
||||
def return_object(self):
|
||||
self.return_date = now()
|
||||
self.save()
|
||||
|
||||
@classmethod
|
||||
def ongoing_loans(cls, obj = None):
|
||||
ongoing = cls.objects.filter(return_date=None)
|
||||
if obj != None:
|
||||
return ongoing.filter(lent_object=obj)
|
||||
else:
|
||||
return ongoing
|
3
loans/tests.py
Normal file
3
loans/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
70
loans/views.py
Normal file
70
loans/views.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
from django.views.generic import DetailView, FormView, RedirectView
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
from inventory.models import Game
|
||||
from .models import AbstractLoan
|
||||
from .forms import BorrowForm
|
||||
|
||||
|
||||
class ReturnView(SingleObjectMixin, RedirectView):
|
||||
# Inherited classes should contain:
|
||||
# model = LoanModel
|
||||
# pattern_name =
|
||||
redirect_slug_field = "slug"
|
||||
|
||||
permanent = False
|
||||
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
loan = self.get_object()
|
||||
loan.return_object()
|
||||
kwargs[self.redirect_slug_field] = getattr(loan.lent_object,
|
||||
loan.lent_object_slug_field)
|
||||
messages.success(self.request, "Rendu effectué.")
|
||||
return super().get_redirect_url(*args, **kwargs)
|
||||
|
||||
|
||||
class BorrowView(SingleObjectMixin, FormView):
|
||||
# Inherited classes should contain:
|
||||
# model = LentObjectModel
|
||||
# loan_model = LoanModel
|
||||
# template_name = "path/to/template.html"
|
||||
form_class = BorrowForm # Update this for a more complex form
|
||||
|
||||
def get_initial(self):
|
||||
initial = super().get_initial()
|
||||
if "loan_mail" in self.request.session:
|
||||
initial["mail"] = self.request.session["loan_mail"]
|
||||
return initial
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
self.object = self.get_object()
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
obj = self.get_object()
|
||||
ongoing = self.loan_model.ongoing_loans(obj)
|
||||
if ongoing.exists():
|
||||
ongoing.get().return_object()
|
||||
loan = self.loan_model(lent_object=obj, mail=form.cleaned_data["mail"])
|
||||
loan.save()
|
||||
self.request.session["loan_mail"] = loan.mail
|
||||
messages.success(self.request, "Votre emprunt est enregistré.")
|
||||
return redirect(self.success_pattern_name,
|
||||
getattr(obj, loan.lent_object_slug_field))
|
||||
|
||||
class DetailLoanView(DetailView):
|
||||
# Inherited classes should contain:
|
||||
# model = LentObjectModel
|
||||
# loan_model = LoanModel
|
||||
# template_name = "path/to/template.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
loans = self.loan_model.ongoing_loans(self.get_object())
|
||||
is_borrowed = loans.exists()
|
||||
context["is_borrowed"] = is_borrowed
|
||||
if is_borrowed:
|
||||
context["loan"] = loans.get()
|
||||
return context
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue