[rentals] Simplify locker index view/template rendering
Also create locker info instances when a new locker unit is created
This commit is contained in:
parent
937646798a
commit
ff723e019d
@ -29,10 +29,11 @@ server = [
|
||||
[tool.black]
|
||||
|
||||
[tool.djlint]
|
||||
profile="django"
|
||||
extension = ".dj.html"
|
||||
indent = 2
|
||||
blank_line_after_tag = "load,extends"
|
||||
ignore = "T003,H017,H030,H031"
|
||||
ignore = "T003,H017,H021,H030,H031"
|
||||
|
||||
[[tool.pdm.source]]
|
||||
url = "https://pypi.org/simple"
|
||||
|
@ -1,5 +1,5 @@
|
||||
from django.core import validators
|
||||
from django.db import models
|
||||
from django.db import models, transaction
|
||||
|
||||
from membershipworks.models import Member
|
||||
|
||||
@ -29,6 +29,17 @@ class LockerUnit(models.Model):
|
||||
rows = models.PositiveIntegerField(default=5)
|
||||
columns = models.PositiveIntegerField(default=2)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self._state.adding:
|
||||
# Create LockerInfo for each locker
|
||||
with transaction.atomic():
|
||||
super().save(self, *args, **kwargs)
|
||||
for column in range(self.columns):
|
||||
for row in range(self.rows):
|
||||
self.lockers.create(column=column + 1, row=row + 1)
|
||||
else:
|
||||
super().save(self, *args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
# TODO: add constraint to check for letter overlaps
|
||||
constraints = [
|
||||
@ -47,20 +58,6 @@ class LockerUnit(models.Model):
|
||||
def number_for_locker(self, column: int, row: int) -> int:
|
||||
return row + self.first_number + (self.columns - column - 1) * self.rows
|
||||
|
||||
def iter_doors(self):
|
||||
for row in range(self.rows):
|
||||
for column in range(self.columns):
|
||||
# TODO: filter could be optimized
|
||||
(locker, _) = self.lockers.get_or_create(
|
||||
locker_unit=self, row=row, column=column
|
||||
)
|
||||
|
||||
yield (
|
||||
self.letter_for_column(column),
|
||||
self.number_for_locker(column, row),
|
||||
locker,
|
||||
)
|
||||
|
||||
|
||||
# TODO: add check constraint to ensure that column and number are within locker_unit bounds
|
||||
class LockerInfo(models.Model):
|
||||
@ -92,11 +89,17 @@ class LockerInfo(models.Model):
|
||||
)
|
||||
]
|
||||
|
||||
@property
|
||||
def letter(self) -> str:
|
||||
return self.locker_unit.letter_for_column(self.column)
|
||||
|
||||
@property
|
||||
def number(self) -> int:
|
||||
return self.locker_unit.number_for_locker(self.column, self.row)
|
||||
|
||||
@property
|
||||
def address(self) -> str:
|
||||
letter = self.locker_unit.letter_for_column(self.column)
|
||||
number = self.locker_unit.number_for_locker(self.column, self.row)
|
||||
return f"{letter}{number}"
|
||||
return f"{self.letter}{self.number}"
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.locker_unit}-{self.address} [{self.renter}]"
|
||||
|
@ -25,22 +25,6 @@
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.locker[data-columns="2"] {
|
||||
grid-template-columns: repeat(2, min-content);
|
||||
}
|
||||
.locker[data-columns="4"] {
|
||||
grid-template-columns: repeat(4, min-content);
|
||||
}
|
||||
.locker[data-columns="6"] {
|
||||
grid-template-columns: repeat(6, min-content);
|
||||
}
|
||||
.locker[data-columns="8"] {
|
||||
grid-template-columns: repeat(8, min-content);
|
||||
}
|
||||
.locker[data-columns="10"] {
|
||||
grid-template-columns: repeat(10, min-content);
|
||||
}
|
||||
|
||||
.locker .door {
|
||||
background-color: hsl(24, 100%, 25%);
|
||||
border: 0.2rem solid black;
|
||||
@ -63,21 +47,22 @@
|
||||
<div>{{ bank.location }}</div>
|
||||
<div class="lockers">
|
||||
{% for unit, lockers in units.items %}
|
||||
<div class="locker" data-columns="{{ unit.columns }}">
|
||||
{% for row, column, locker, form in lockers %}
|
||||
<div class="dropdown">
|
||||
<div class="locker"
|
||||
style="grid-template-columns: repeat({{ unit.columns }}, min-content);">
|
||||
{% for locker_form in lockers %}
|
||||
<div class="dropdown"
|
||||
style="grid-row-start: {{ locker_form.instance.row|add:"1" }}; grid-column-start: {{ locker_form.instance.column|add:"
|
||||
1>
|
||||
<span class="door {{ perms.rentals.view_lockerinfo|yesno:"btn dropdown-toggle," }}"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
data-rented="{{ locker.renter|yesno:"true,false" }}"
|
||||
data-row="{{ row }}"
|
||||
data-column="{{ column }}">
|
||||
<h3 class="locker-name">{{ bank.initial }}{{ row }}{{ column }}</h3>
|
||||
data-rented="{{ locker_form.instance.renter|yesno:"true,false" }}">
|
||||
<h3 class="locker-address">{{ locker_form.instance.address }}</h3>
|
||||
<div class="locker-status">
|
||||
{% if locker.renter is not None %}
|
||||
{% if locker_form.instance.renter is not None %}
|
||||
{% if perms.rentals.view_lockerinfo %}
|
||||
{{ locker.renter }}
|
||||
{{ locker_form.instance.renter }}
|
||||
{% else %}
|
||||
Occupied
|
||||
{% endif %}
|
||||
@ -88,19 +73,19 @@
|
||||
</span>
|
||||
{% if perms.rentals.view_lockerinfo %}
|
||||
<div class="dropdown-menu">
|
||||
<div class="dropdown-header">{{ locker }}</div>
|
||||
<div class="dropdown-header">{{ locker_form.instance }}</div>
|
||||
<form class="p-2"
|
||||
action="{% url 'rentals:locker' locker.id %}"
|
||||
action="{% url 'rentals:locker' locker_form.instance.id %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
<fieldset {{ perms.rentals.change_lockerinfo|yesno:",disabled" }}>
|
||||
{% for field in form.visible_fields %}
|
||||
{% for field in locker_form.visible_fields %}
|
||||
<div class="form-floating mb-3">
|
||||
{{ field }}
|
||||
{{ field.label_tag }}
|
||||
{{ field.errors }}
|
||||
{% if field.help_text %}
|
||||
<p class="form-text">
|
||||
<p class="form-text text-nowrap">
|
||||
{{ field.help_text|safe }}
|
||||
</p>
|
||||
{% endif %}
|
||||
@ -108,7 +93,7 @@
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
{% if perms.rentals.change_lockerinfo %}
|
||||
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
|
||||
{% for hidden in locker_form.hidden_fields %}{{ hidden }}{% endfor %}
|
||||
<input class="btn btn-primary" type="submit" value="Submit">
|
||||
{% endif %}
|
||||
</form>
|
||||
|
@ -11,10 +11,7 @@ from .forms import LockerInfoForm
|
||||
def lockerIndex(request):
|
||||
locker_banks = {
|
||||
bank: {
|
||||
unit: [
|
||||
(col, num, locker, LockerInfoForm(instance=locker))
|
||||
for col, num, locker in unit.iter_doors()
|
||||
]
|
||||
unit: [LockerInfoForm(instance=locker) for locker in unit.lockers.all()]
|
||||
for unit in bank.units.all()
|
||||
}
|
||||
for bank in LockerBank.objects.all()
|
||||
|
Loading…
Reference in New Issue
Block a user