Skip to content
Snippets Groups Projects
Commit f930021c authored by Tobias Mieves's avatar Tobias Mieves :sparkles:
Browse files

Merge branch 'feature/dependent-wishes' into 'develop'

Dependent Wishes

See merge request tobiasff3200/wishlist!141
parents ae0daec0 4d48acae
No related branches found
No related tags found
No related merge requests found
# Generated by Django 5.0.6 on 2024-08-06 14:11
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wishlist', '0008_wish_favorite'),
]
operations = [
migrations.AlterModelOptions(
name='wish',
options={'ordering': ('-favorite',)},
),
migrations.AddField(
model_name='wish',
name='depends_on',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
related_name='dependent_wishes', to='wishlist.wish'),
),
]
......@@ -19,11 +19,16 @@ class Wish(models.Model):
User, related_name="reserved_wishes", through="Reservation"
)
favorite = models.BooleanField(default=False)
depends_on = models.ForeignKey('Wish', on_delete=models.SET_NULL, related_name="dependent_wishes", null=True,
blank=True)
class Meta:
ordering = ("-favorite",)
def is_reservation_possible(self):
if self.depends_on is not None and len(self.depends_on.reserved_by.all()) == 0:
return False
reserved = (Reservation.objects.filter(wish=self).aggregate(Sum("quantity")))[
"quantity__sum"
]
......@@ -31,6 +36,9 @@ class Wish(models.Model):
return reserved < self.quantity
return True
def __str__(self):
return self.text
class Group(models.Model):
name = models.TextField(max_length=100)
......
......@@ -29,11 +29,19 @@
</label>
{{ form.quantity }}
</div>
<div class="form-control w-full max-w-xs">
<label class="label" for="{{ form.depends_on.id_for_label }}">
<span class="label-text">{{ form.depends_on.label_tag }}</span>
<span class="label-text-alt">{{ form.depends_on.errors }}</span>
</label>
{{ form.depends_on }}
</div>
<div class="card-actions justify-end mt-4">
<button class="btn btn-primary" type="submit">Hinzufügen</button>
</div>
</div>
</form>
<div class="hidden select select-bordered w-full max-w-xs"></div>
</div>
</div>
</div>
......
......@@ -29,6 +29,13 @@
</label>
{{ form.quantity }}
</div>
<div class="form-control w-full max-w-xs">
<label class="label" for="{{ form.depends_on.id_for_label }}">
<span class="label-text">{{ form.depends_on.label_tag }}</span>
<span class="label-text-alt">{{ form.depends_on.errors }}</span>
</label>
{{ form.depends_on }}
</div>
<div class="card-actions justify-end mt-4">
<button class="btn btn-primary" type="submit">Speichern</button>
</div>
......
......@@ -20,74 +20,7 @@
<a href="{% url 'createWish' list_owner.id %}" class="btn w-full mb-4 lg:hidden">Neuen Wunsch hinzufügen</a>
<div>
{% for wish in wishes %}
<div class="card shadow-lg compact">
<div class="card-body">
<h2 class="card-title w-full flex flex-row justify-between">
<span>
{{ wish.text }}
{% if wish.wish_for != user and wish.reserved_by.all|length > 0 %}
<div class="badge ml-2">
Reserviert von
{% for reservation in wish.reservation_set.all %}
{% if wish.quantity > 1 or reservation.quantity > wish.quantity %}
{{ reservation.quantity }}x
{% endif %}
{{ reservation.user }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</span>
<a {% if list_owner == user %}href="{% url 'toggleFavorite' wish.id %}"{% endif %}
class="text-4xl">
{% if wish.favorite %}★{% elif list_owner == user %}☆{% endif %}
</a>
</h2>
{% if wish.quantity > 1 %}
<p>
<span class="italic font-bold">Anzahl: {{ wish.quantity }}</span>
</p>
{% endif %}
{% if wish.owner != list_owner %}
<p>
<span class="italic">Vorschlag von {{ wish.owner }}</span>
<span class="tooltip tooltip-bottom inline-flex"
data-tip="{{ list_owner }} kann diesen Vorschlag nicht sehen. Für weitere Fragen bitte an {{ wish.owner }} wenden.">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
class="w-4 h-4 stroke-current">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</span>
</p>
{% endif %}
{% if wish.link %}
<div>
<a class="link" href="{{ wish.link }}" target="_blank"
rel="noopener noreferrer">Link</a>
</div>
{% endif %}
<div class="card-actions">
{% if wish.owner == user %}
<a class="btn btn-sm"
href="{% url 'deleteWish' wish.id %}?list_owner={{ list_owner.id }}">Löschen</a>
<a class="btn btn-sm"
href="{% url 'editWish' wish.id %}?list_owner={{ list_owner.id }}">Bearbeiten</a>
{% endif %}
{% if wish.wish_for != user and wish.is_reservation_possible %}
<a class="btn btn-sm"
href="{% url 'reserveWish' wish.id %}?list_owner={{ list_owner.id }}">Reservieren</a>{% endif %}
{% if wish.wish_for != user and user in wish.reserved_by.all %}
<a class="btn btn-sm"
href="{% url 'cancelReserveWish' wish.id %}?list_owner={{ list_owner.id }}">
Nicht mehr reservieren
</a>
{% endif %}
</div>
</div>
</div>
{% include "wishlist/wish_template.html" with wish=wish %}
{% empty %}
<div class="alert alert-success shadow-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none"
......
<div class="card shadow-lg compact">
<div class="card-body">
<h2 class="card-title w-full flex flex-row justify-between">
<span>
{{ wish.text }}
{% if wish.wish_for != user and wish.reserved_by.all|length > 0 %}
<div class="badge ml-2">
Reserviert von
{% for reservation in wish.reservation_set.all %}
{% if wish.quantity > 1 or reservation.quantity > wish.quantity %}
{{ reservation.quantity }}x
{% endif %}
{{ reservation.user }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
</span>
<a {% if list_owner == user %}href="{% url 'toggleFavorite' wish.id %}"{% endif %}
class="text-4xl">
{% if wish.favorite %}★{% elif list_owner == user %}☆{% endif %}
</a>
</h2>
{% if wish.quantity > 1 %}
<p>
<span class="italic font-bold">Anzahl: {{ wish.quantity }}</span>
</p>
{% endif %}
{% if wish.owner != list_owner %}
<p>
<span class="italic">Vorschlag von {{ wish.owner }}</span>
<span class="tooltip tooltip-bottom inline-flex"
data-tip="{{ list_owner }} kann diesen Vorschlag nicht sehen. Für weitere Fragen bitte an {{ wish.owner }} wenden.">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
class="w-4 h-4 stroke-current">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</span>
</p>
{% endif %}
{% if wish.link %}
<div>
<a class="link" href="{{ wish.link }}" target="_blank"
rel="noopener noreferrer">Link</a>
</div>
{% endif %}
<div class="card-actions">
{% if wish.owner == user %}
<a class="btn btn-sm"
href="{% url 'deleteWish' wish.id %}?list_owner={{ list_owner.id }}">Löschen</a>
<a class="btn btn-sm"
href="{% url 'editWish' wish.id %}?list_owner={{ list_owner.id }}">Bearbeiten</a>
{% endif %}
{% if wish.wish_for != user and wish.is_reservation_possible %}
<a class="btn btn-sm"
href="{% url 'reserveWish' wish.id %}?list_owner={{ list_owner.id }}">Reservieren</a>{% endif %}
{% if wish.wish_for != user and user in wish.reserved_by.all %}
<a class="btn btn-sm"
href="{% url 'cancelReserveWish' wish.id %}?list_owner={{ list_owner.id }}">
Nicht mehr reservieren
</a>
{% endif %}
</div>
{% if wish.dependent_wishes.all %}
<div class="collapse collapse-arrow {% if wish.reserved_by.all|length > 0 %}collapse-open{% endif %}">
<input type="checkbox" />
<div class="collapse-title text-xl font-medium">Abhängige Wünsche</div>
<div class="collapse-content">
{% for dep_wish in wish.dependent_wishes.all %}
{% include "wishlist/wish_template.html" with wish=dep_wish %}
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>
......@@ -45,9 +45,9 @@ def wishListView(request: HttpRequest, list_owner):
raise PermissionDenied()
# Get all requests except those that are from others for the user
if list_owner == request.user:
wishes = Wish.objects.filter(wish_for=list_owner).filter(owner=request.user)
wishes = Wish.objects.filter(wish_for=list_owner).filter(owner=request.user).filter(depends_on__isnull=True)
else:
wishes = Wish.objects.filter(wish_for=list_owner)
wishes = Wish.objects.filter(wish_for=list_owner).filter(depends_on__isnull=True)
return render(
request,
......@@ -61,7 +61,7 @@ class CreateWishView(LoginRequiredMixin, CreateView):
template_name = "wishlist/create-wish.html"
form_class = modelform_factory(
Wish,
fields=("text", "link", "quantity"),
fields=("text", "link", "quantity", "depends_on"),
labels={"text": "Wunsch", "link": "Link", "quantity": "Anzahl"},
widgets={
"text": django.forms.TextInput(
......@@ -73,9 +73,15 @@ class CreateWishView(LoginRequiredMixin, CreateView):
"quantity": django.forms.NumberInput(
attrs={"class": "input input-bordered w-full max-w-xs", "min": 1}
),
"depends_on": django.forms.Select(attrs={"class": "select select-bordered w-full max-w-xs"})
},
)
def get_form(self, form_class=None):
form = super().get_form(form_class)
form.fields['depends_on'].queryset = Wish.objects.filter(wish_for_id=self.kwargs.get("list_owner"))
return form
def form_valid(self, form):
list_owner = self.kwargs["list_owner"]
if form.is_valid():
......@@ -88,6 +94,7 @@ class CreateWishView(LoginRequiredMixin, CreateView):
quantity=data.get("quantity"),
owner=self.request.user,
wish_for=list_owner,
depends_on=data.get("depends_on")
)
wish.save()
if self.request.user != list_owner:
......@@ -172,7 +179,7 @@ class EditWishView(LoginRequiredMixin, UpdateView):
template_name = "wishlist/edit-wish.html"
form_class = modelform_factory(
Wish,
fields=("text", "link", "quantity"),
fields=("text", "link", "quantity", "depends_on"),
labels={"text": "Wunsch", "link": "Link", "quantity": "Anzahl"},
widgets={
"text": django.forms.TextInput(
......@@ -184,9 +191,15 @@ class EditWishView(LoginRequiredMixin, UpdateView):
"quantity": django.forms.NumberInput(
attrs={"class": "input input-bordered w-full max-w-xs", "min": 1}
),
"depends_on": django.forms.Select(attrs={"class": "select select-bordered w-full max-w-xs"})
},
)
def get_form(self, form_class=None):
form = super().get_form(form_class)
form.fields['depends_on'].queryset = Wish.objects.filter(wish_for_id=self.request.GET.get("list_owner"))
return form
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
context["all_users"] = get_all_users_filtered(self.request)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment