Skip to content

Commit

Permalink
Merge pull request #793 from hackerspace-ntnu/713-add-date_from-on-it…
Browse files Browse the repository at this point in the history
…em-loans

713 add date from on item loans
  • Loading branch information
CJGutz authored Apr 3, 2024
2 parents 2d29f5d + be8b322 commit a4f44f0
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 140 deletions.
6 changes: 5 additions & 1 deletion files/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-04-03 20:23+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -22,6 +22,10 @@ msgstr ""
msgid "Fjern"
msgstr "Remove"

#: files/templates/files/_gallery_include.html:25
msgid "VELG"
msgstr "SELECT"

#: files/templates/files/_gallery_include.html:29
msgid "Bildet er valgt"
msgstr "The image is selected"
Expand Down
6 changes: 5 additions & 1 deletion files/locale/nb/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-04-03 20:23+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -22,6 +22,10 @@ msgstr ""
msgid "Fjern"
msgstr ""

#: files/templates/files/_gallery_include.html:25
msgid "VELG"
msgstr ""

#: files/templates/files/_gallery_include.html:29
msgid "Bildet er valgt"
msgstr ""
Expand Down
2 changes: 1 addition & 1 deletion files/templates/files/_gallery_include.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
var thumb_preview = document.querySelector('#thumb-preview');

document.addEventListener('click', function(e) {
if(e.target.innerText === "VELG") {
if(e.target.innerText === "{% trans 'VELG' %}") { // This is really funny to me
var selectedImgId = e.target.attributes.value.value;
thumbnail_input.value = selectedImgId;
thumb_preview.style.backgroundImage = "url('/files/image-view/" + selectedImgId;
Expand Down
2 changes: 1 addition & 1 deletion internalportal/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-04-03 19:21+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
2 changes: 1 addition & 1 deletion internalportal/locale/nb/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-02-28 18:43+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
8 changes: 6 additions & 2 deletions inventory/locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-04-03 19:21+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -18,7 +18,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: inventory/templates/inventory/edit_item.html:12
#: inventory/models/item_loan.py:25
msgid "Lån fra"
msgstr "Borrow from"

#: inventory/templates/inventory/edit_item.html:13
msgid "Rediger lagerinnslag"
msgstr "Edit inventory item"

Expand Down
8 changes: 6 additions & 2 deletions inventory/locale/nb/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-13 20:22+0100\n"
"POT-Creation-Date: 2024-04-03 19:21+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand All @@ -18,7 +18,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: inventory/templates/inventory/edit_item.html:12
#: inventory/models/item_loan.py:25
msgid "Lån fra"
msgstr ""

#: inventory/templates/inventory/edit_item.html:13
msgid "Rediger lagerinnslag"
msgstr ""

Expand Down
19 changes: 19 additions & 0 deletions inventory/migrations/0030_alter_itemloan_loan_from.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 3.2.18 on 2024-02-28 18:40

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('inventory', '0029_equipment'),
]

operations = [
migrations.AlterField(
model_name='itemloan',
name='loan_from',
field=models.DateField(default=django.utils.timezone.now, verbose_name='Lån fra'),
),
]
3 changes: 2 additions & 1 deletion inventory/models/item_loan.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.core.validators import MinValueValidator
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from applications.validators import validate_phone_number

Expand All @@ -21,7 +22,7 @@ class ItemLoan(models.Model):
amount = models.IntegerField("Antall", validators=[MinValueValidator(1)])

# Automatically set once the application is accepted
loan_from = models.DateField("Utlånt fra", default=timezone.now, blank=True)
loan_from = models.DateField(_("Lån fra"), default=timezone.now)
loan_to = models.DateField("Lån til")
purpose = models.CharField("Formål", max_length=50)

Expand Down
78 changes: 42 additions & 36 deletions inventory/static/inventory/js/loan_app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
document.addEventListener("DOMContentLoaded", function() {
const datepickers = document.querySelectorAll('.datepicker');

internationalization = {
months: [
'Januar',
Expand Down Expand Up @@ -37,45 +35,53 @@ document.addEventListener("DOMContentLoaded", function() {
weekdaysAbbrev: ['S','M','T','O','T','F','L']
}

for (dp of datepickers) {
options = {
format: 'dd.mm.yyyy',
firstDay: 1,
i18n: internationalization,
minDate: new Date()
}
const maxDateStr = dp.getAttribute('data-max-date')
if (maxDateStr) {
options.maxDate = new Date(maxDateStr)
}
M.Datepicker.init(dp, options);
const loanFromDateEl = document.getElementById('id_loan_from');
const loanToDateEl = document.getElementById('id_loan_to');

options = {
format: 'dd.mm.yyyy',
firstDay: 1,
i18n: internationalization
}

initDatepickers(loanToDateEl, loanFromDateEl, maxLoanDays, loanFromMaxDate, options)
loanFromDateEl.addEventListener('change', () => {
updateLoanToDatepicker(loanToDateEl, loanFromDateEl, options, maxLoanDays)
});

// Vis og gjem deler som relateres til påmeldinger
var reg_box = document.getElementsByClassName('reg-box')[0];
var reg_check = document.getElementsByName('registration')[0]
var ext_reg = document.getElementsByClassName('ext-reg')[0];
});

if(reg_check.checked) {
reg_box.classList.remove('hide');
ext_reg.classList.add('hide');
function parseFormattedDate(dateString) {
const dateParts = dateString.split('.');
return new Date(dateParts[2], dateParts[1]-1, dateParts[0]);
}

function initDatepickers(loanToEl, loanFromEl, maxLoanDays, loanFromMaxDate, dpOptions) {
const toDateOptions = dpOptions
const fromDateOptions = {
...toDateOptions,
}
else {
reg_box.classList.add('hide');
ext_reg.classList.remove('hide');

fromDateOptions.minDate = parseFormattedDate(loanFromEl.value);
if (loanFromMaxDate) {
fromDateOptions.maxDate = new Date(loanFromMaxDate);
}

reg_check.onchange = function() {
if(this.checked) {
reg_box.classList.remove('hide');
ext_reg.classList.add('hide');
}
else {
reg_box.classList.add('hide');
ext_reg.classList.remove('hide');
document.getElementById('id_external_registration').value = '';
}
};
M.Datepicker.init(loanFromEl, fromDateOptions);
M.Datepicker.init(loanToEl, toDateOptions);

});
updateLoanToDatepicker(loanToEl, loanFromEl, toDateOptions, maxLoanDays)
}

function updateLoanToDatepicker(loanToEl, loanFromEl, datepickerOptions, maxLoanDays) {
const loanFromDate = parseFormattedDate(loanFromEl.value)

datepickerOptions.minDate = loanFromDate

if (maxLoanDays) {
const maxDate = new Date(loanFromDate)
maxDate.setDate(loanFromDate.getDate() + maxLoanDays)
datepickerOptions.maxDate = maxDate
}
M.Datepicker.init(loanToEl, datepickerOptions);
}
23 changes: 19 additions & 4 deletions inventory/templates/inventory/loan_apply.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,23 @@ <h4>Lånesøknad - {{ item.name }}</h4>
<h5>Lånedetaljer</h5>
</div>
<div class="input-field col s12 m6">
{{ form.amount }}
<label for="{{ form.amount.id_for_label }}">{{ form.amount.label }}</label>
<span class="helper-text hs-red-text">{{ form.amount.errors }}</span>
<i class="material-icons prefix">date_range</i>
{{ form.loan_from }}
<label for="{{ form.loan_from.id_for_label }}">{{ form.loan_from.label }}</label>
<span class="helper-text hs-red-text">{{ form.loan_from.errors }}</span>
</div>
<div class="input-field col s12 m6">
<i class="material-icons prefix">date_range</i>
{{ form.loan_to }}
<label for="{{ form.loan_to.id_for_label }}">{{ form.loan_to.label }}</label>
<span class="helper-text hs-red-text">{{ form.loan_to.errors }}</span>
</div>
<div class="input-field col s12 m12">
<div class="input-field col s12 m6">
{{ form.amount }}
<label for="{{ form.amount.id_for_label }}">{{ form.amount.label }}</label>
<span class="helper-text hs-red-text">{{ form.amount.errors }}</span>
</div>
<div class="input-field col s12 m6">
{{ form.purpose }}
<label for="{{ form.purpose.id_for_label }}">{{ form.purpose.label }}</label>
<span class="helper-text hs-red-text">{{ form.purpose.errors }}</span>
Expand Down Expand Up @@ -109,6 +115,15 @@ <h5>Medlemsfordeler</h5>
</div>
</div>

<script>
const maxLoanDays = {{ item.max_loan_duration|default:"undefined" }};

{% if loan_from_max_date %}
const loanFromMaxDate = "{{ loan_from_max_date|date:'Y.m.d' }}";
{% else %}
const loanFromMaxDate = undefined;
{% endif %}
</script>
<script src="{% static 'inventory/js/loan_app.js' %}"></script>

{% endblock %}
36 changes: 30 additions & 6 deletions inventory/views/item_loan.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime, timedelta
from datetime import date, datetime, timedelta

from dateutil.relativedelta import relativedelta
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import HttpResponseRedirect
Expand Down Expand Up @@ -136,6 +137,7 @@ class ItemLoanApplicationView(CreateView):
fields = [
"item",
"amount",
"loan_from",
"loan_to",
"purpose",
"contact_name",
Expand All @@ -146,6 +148,7 @@ class ItemLoanApplicationView(CreateView):
template_name = "inventory/loan_apply.html"
success_message = "Lånesøknaden er registrert!"
success_url = reverse_lazy("inventory:inventory")
months_max_ahead = 1

def get_success_url(self):
# SuccessMessageMixin doesn't actually work so fuck it
Expand Down Expand Up @@ -185,16 +188,18 @@ def get(self, *args, **kwargs):
def get_form(self, *args, **kwargs):
# Add the datepicker class to the loan to field before it's sent off
form = super().get_form(*args, **kwargs)
max_duration = Item.objects.get(id=self.kwargs["pk"]).max_loan_duration
if max_duration is not None:
max_date = datetime.now() + timedelta(days=max_duration)
form.fields["loan_to"].widget.attrs["data-max-date"] = max_date
form.fields["loan_to"].widget.attrs["class"] = "datepicker"
form.fields["loan_from"].widget.attrs["class"] = "datepicker"
form.fields["loan_from"].widget.format = "%d.%m.%Y" # Set date format
form.fields["loan_to"].widget.format = "%d.%m.%Y" # Set date format
return form

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["item"] = Item.objects.get(id=self.kwargs["pk"])
context["loan_from_max_date"] = date.today() + relativedelta(
months=self.months_max_ahead
)
return context

def form_valid(self, form):
Expand All @@ -210,14 +215,33 @@ def form_valid(self, form):
max_duration = Item.objects.get(id=self.kwargs["pk"]).max_loan_duration
# Convert 'loan to' date from datetime.date to datetime.datetime (i.e. add time 00:00)
# (because same type is required for the comparison check)
loan_from_datetime = datetime.combine(
form.instance.loan_from, datetime.max.time()
)
loan_to_datetime = datetime.combine(form.instance.loan_to, datetime.min.time())
if max_duration and loan_to_datetime > datetime.now() + timedelta(

if max_duration and loan_to_datetime > loan_from_datetime + timedelta(
days=max_duration
):
form.errors[
"loan_to"
] = f"Du kan ikke låne denne gjenstanden lenger enn {max_duration} dager"
return self.render_to_response(self.get_context_data(form=form))
if loan_to_datetime < loan_from_datetime:
form.errors["loan_from"] = "Startdato for lån må være før sluttdato for lån"
return self.render_to_response(self.get_context_data(form=form))
if loan_from_datetime < datetime.now():
form.errors[
"loan_from"
] = "Du kan ikke starte å låne denne gjenstanden før i dag"
return self.render_to_response(self.get_context_data(form=form))
if loan_from_datetime.date() > (
date.today() + relativedelta(months=self.months_max_ahead)
):
form.errors[
"loan_from"
] = f"""Du kan ikke starte å låne denne gjenstanden mer enn {self.months_max_ahead} måned frem i tid"""
return self.render_to_response(self.get_context_data(form=form))

# bit ugly but it works
user = self.request.user
Expand Down
Loading

0 comments on commit a4f44f0

Please sign in to comment.