From b11338843826f99803800ba85c08c5d28b8ac3e2 Mon Sep 17 00:00:00 2001 From: erlendska Date: Wed, 21 Feb 2024 18:53:54 +0100 Subject: [PATCH 01/11] added loan_from to item_loan.py in \models and \views --- inventory/models/item_loan.py | 2 +- inventory/templates/inventory/loan_apply.html | 28 +++++++++++-------- inventory/views/item_loan.py | 1 + 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/inventory/models/item_loan.py b/inventory/models/item_loan.py index 6e631ce90..5848b81ac 100644 --- a/inventory/models/item_loan.py +++ b/inventory/models/item_loan.py @@ -21,7 +21,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) diff --git a/inventory/templates/inventory/loan_apply.html b/inventory/templates/inventory/loan_apply.html index bdd6618f2..43b5f2db6 100644 --- a/inventory/templates/inventory/loan_apply.html +++ b/inventory/templates/inventory/loan_apply.html @@ -36,17 +36,23 @@

Lånesøknad - {{ item.name }}

Lånedetaljer
-
- {{ form.amount }} - - {{ form.amount.errors }} -
-
- date_range - {{ form.loan_to }} - - {{ form.loan_to.errors }} -
+ +
+ date_range + {{ form.loan_from }} + + {{ form.loan_from.errors }} +
+
+ date_range + {{ form.loan_to }} + + {{ form.loan_to.errors }} +
+
+ {{ form.amount }} + + {{ form.amount.errors }}
{{ form.purpose }} diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index 69cc20592..21b1464af 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -136,6 +136,7 @@ class ItemLoanApplicationView(CreateView): fields = [ "item", "amount", + "loan_from", "loan_to", "purpose", "contact_name", From 57979c82d587b02a93622c2bfad747045939ad93 Mon Sep 17 00:00:00 2001 From: erlendska Date: Wed, 21 Feb 2024 19:18:43 +0100 Subject: [PATCH 02/11] added errors for loan_from parameter --- inventory/views/item_loan.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index 21b1464af..03c7250ae 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -211,6 +211,9 @@ 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.min.time() + ) loan_to_datetime = datetime.combine(form.instance.loan_to, datetime.min.time()) if max_duration and loan_to_datetime > datetime.now() + timedelta( days=max_duration @@ -219,6 +222,19 @@ def form_valid(self, form): "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 > datetime.now() + timedelta(days=14): + form.errors[ + "loan_from" + ] = "Du kan ikke starte å låne denne gjenstanden mer enn 14 dager frem i tid" + return self.render_to_response(self.get_context_data(form=form)) # bit ugly but it works user = self.request.user From c61416f4dcc124da3cd579a0c653d4da4175b76d Mon Sep 17 00:00:00 2001 From: erlendska Date: Wed, 21 Feb 2024 19:42:01 +0100 Subject: [PATCH 03/11] fixed view and model --- inventory/models/item_loan.py | 2 +- inventory/views/item_loan.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/inventory/models/item_loan.py b/inventory/models/item_loan.py index 5848b81ac..c3fe4feb1 100644 --- a/inventory/models/item_loan.py +++ b/inventory/models/item_loan.py @@ -21,7 +21,7 @@ class ItemLoan(models.Model): amount = models.IntegerField("Antall", validators=[MinValueValidator(1)]) # Automatically set once the application is accepted - loan_from = models.DateField("Lån fra", default=timezone.now) + loan_from = models.DateField("Lån fra", default=timezone.now().strftime("%d.%m.%Y")) loan_to = models.DateField("Lån til") purpose = models.CharField("Formål", max_length=50) diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index 03c7250ae..e2754a491 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -191,6 +191,7 @@ def get_form(self, *args, **kwargs): 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" return form def get_context_data(self, **kwargs): From 9e81fdf91011a5c264cb23a864b10c67f64a72be Mon Sep 17 00:00:00 2001 From: erlendska Date: Wed, 28 Feb 2024 18:43:16 +0100 Subject: [PATCH 04/11] final changes --- .../0030_alter_itemloan_loan_from.py | 19 +++++++++++++++++++ inventory/models/item_loan.py | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 inventory/migrations/0030_alter_itemloan_loan_from.py diff --git a/inventory/migrations/0030_alter_itemloan_loan_from.py b/inventory/migrations/0030_alter_itemloan_loan_from.py new file mode 100644 index 000000000..610ed34ff --- /dev/null +++ b/inventory/migrations/0030_alter_itemloan_loan_from.py @@ -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'), + ), + ] diff --git a/inventory/models/item_loan.py b/inventory/models/item_loan.py index c3fe4feb1..b733ddb8a 100644 --- a/inventory/models/item_loan.py +++ b/inventory/models/item_loan.py @@ -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 @@ -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("Lån fra", default=timezone.now().strftime("%d.%m.%Y")) + 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) From 326b31f84addbbaf4eae0297e56f22600999071e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Wed, 28 Feb 2024 18:46:52 +0100 Subject: [PATCH 05/11] create i18n files for inventory --- .../locale/en/LC_MESSAGES/django.po | 28 +++++++++---------- .../locale/nb/LC_MESSAGES/django.po | 28 +++++++++---------- inventory/locale/en/LC_MESSAGES/django.po | 6 +++- inventory/locale/nb/LC_MESSAGES/django.po | 6 +++- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/internalportal/locale/en/LC_MESSAGES/django.po b/internalportal/locale/en/LC_MESSAGES/django.po index 2b60b44d7..a3723655a 100644 --- a/internalportal/locale/en/LC_MESSAGES/django.po +++ b/internalportal/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 17:21+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 \n" "Language-Team: LANGUAGE \n" @@ -203,7 +203,7 @@ msgstr "Email" msgid "Gå tilbake" msgstr "Go back" -#: internalportal/templates/internalportal/applications/approved_email.txt:2 +#: internalportal/templates/internalportal/applications/approved_email.txt:1 #, python-format msgid "" "Hei %(name)s,\n" @@ -235,7 +235,7 @@ msgstr "" "Best regards,\n" "%(application_group)s " -#: internalportal/templates/internalportal/applications/denied_email.txt:2 +#: internalportal/templates/internalportal/applications/denied_email.txt:1 #, python-format msgid "" "Hei %(name)s,\n" @@ -261,7 +261,7 @@ msgstr "" "Best regards,\n" "%(application_group)s " -#: internalportal/templates/internalportal/applications/interview_email.txt:2 +#: internalportal/templates/internalportal/applications/interview_email.txt:1 #, python-format msgid "" "Hei %(application_name)s,\n" @@ -288,7 +288,7 @@ msgstr "" "\n" "The proposed time for the interview is %(start_time)s in " -#: internalportal/templates/internalportal/applications/interview_email.txt:13 +#: internalportal/templates/internalportal/applications/interview_email.txt:12 msgid "Med vennlig hilsen" msgstr "Best regards" @@ -393,42 +393,42 @@ msgstr "Admin panel" msgid "Medlemsliste for dørtilgang" msgstr "Member list for door access" -#: internalportal/templates/internalportal/internalportal.html:176 +#: internalportal/templates/internalportal/internalportal.html:177 msgid "Søkere" msgstr "Applicants" -#: internalportal/templates/internalportal/internalportal.html:178 +#: internalportal/templates/internalportal/internalportal.html:179 msgid "venter" msgstr "waiting" -#: internalportal/views.py:108 +#: internalportal/views.py:109 msgid "Søknad sendt videre til neste gruppe" msgstr "Application forwarded to the next group" -#: internalportal/views.py:117 +#: internalportal/views.py:118 msgid "Søknaden finnes ikke" msgstr "The application does not exist" -#: internalportal/views.py:132 +#: internalportal/views.py:133 msgid "Søknaden har ingen flere grupper å gå til" msgstr "The application has no more groups to go to" -#: internalportal/views.py:141 +#: internalportal/views.py:142 #, python-brace-format msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." msgstr "The group {group_name} does not exist. Contact the administrator." -#: internalportal/views.py:158 +#: internalportal/views.py:159 #, python-brace-format msgid "Gruppen {group} har ingen ledere. Kontakt administrator." msgstr "" "The group {group} does not have any leaders. Contact the administrator." -#: internalportal/views.py:169 +#: internalportal/views.py:170 msgid "Søknad sendt videre" msgstr "Application forwarded" -#: internalportal/views.py:270 +#: internalportal/views.py:271 msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." msgstr "" "Have the user log in with Feide first and use the applicant's NTNU email." diff --git a/internalportal/locale/nb/LC_MESSAGES/django.po b/internalportal/locale/nb/LC_MESSAGES/django.po index e8b05a68d..2e34c909c 100644 --- a/internalportal/locale/nb/LC_MESSAGES/django.po +++ b/internalportal/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 17:21+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 \n" "Language-Team: LANGUAGE \n" @@ -200,7 +200,7 @@ msgstr "" msgid "Gå tilbake" msgstr "" -#: internalportal/templates/internalportal/applications/approved_email.txt:2 +#: internalportal/templates/internalportal/applications/approved_email.txt:1 #, python-format msgid "" "Hei %(name)s,\n" @@ -218,7 +218,7 @@ msgid "" "%(application_group)s" msgstr "" -#: internalportal/templates/internalportal/applications/denied_email.txt:2 +#: internalportal/templates/internalportal/applications/denied_email.txt:1 #, python-format msgid "" "Hei %(name)s,\n" @@ -233,7 +233,7 @@ msgid "" "%(application_group)s" msgstr "" -#: internalportal/templates/internalportal/applications/interview_email.txt:2 +#: internalportal/templates/internalportal/applications/interview_email.txt:1 #, python-format msgid "" "Hei %(application_name)s,\n" @@ -249,7 +249,7 @@ msgid "" "Foreslått tidspunkt for intervjuet er %(start_time)s i " msgstr "" -#: internalportal/templates/internalportal/applications/interview_email.txt:13 +#: internalportal/templates/internalportal/applications/interview_email.txt:12 msgid "Med vennlig hilsen" msgstr "" @@ -354,40 +354,40 @@ msgstr "" msgid "Medlemsliste for dørtilgang" msgstr "" -#: internalportal/templates/internalportal/internalportal.html:176 +#: internalportal/templates/internalportal/internalportal.html:177 msgid "Søkere" msgstr "" -#: internalportal/templates/internalportal/internalportal.html:178 +#: internalportal/templates/internalportal/internalportal.html:179 msgid "venter" msgstr "" -#: internalportal/views.py:108 +#: internalportal/views.py:109 msgid "Søknad sendt videre til neste gruppe" msgstr "" -#: internalportal/views.py:117 +#: internalportal/views.py:118 msgid "Søknaden finnes ikke" msgstr "" -#: internalportal/views.py:132 +#: internalportal/views.py:133 msgid "Søknaden har ingen flere grupper å gå til" msgstr "" -#: internalportal/views.py:141 +#: internalportal/views.py:142 #, python-brace-format msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." msgstr "" -#: internalportal/views.py:158 +#: internalportal/views.py:159 #, python-brace-format msgid "Gruppen {group} har ingen ledere. Kontakt administrator." msgstr "" -#: internalportal/views.py:169 +#: internalportal/views.py:170 msgid "Søknad sendt videre" msgstr "" -#: internalportal/views.py:270 +#: internalportal/views.py:271 msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." msgstr "" diff --git a/inventory/locale/en/LC_MESSAGES/django.po b/inventory/locale/en/LC_MESSAGES/django.po index 7a0648aef..17ac06b21 100644 --- a/inventory/locale/en/LC_MESSAGES/django.po +++ b/inventory/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 17:21+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 \n" "Language-Team: LANGUAGE \n" @@ -18,6 +18,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: inventory/models/item_loan.py:25 +msgid "Lån fra" +msgstr "Borrow from" + #: inventory/templates/inventory/inventory.html:12 msgid "Lager" msgstr "Inventory" diff --git a/inventory/locale/nb/LC_MESSAGES/django.po b/inventory/locale/nb/LC_MESSAGES/django.po index 64a0110de..9837a87b1 100644 --- a/inventory/locale/nb/LC_MESSAGES/django.po +++ b/inventory/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-27 17:21+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 \n" "Language-Team: LANGUAGE \n" @@ -18,6 +18,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: inventory/models/item_loan.py:25 +msgid "Lån fra" +msgstr "" + #: inventory/templates/inventory/inventory.html:12 msgid "Lager" msgstr "" From 2408ba8a2223c2d1cbddd2310172df0a16ccb73a Mon Sep 17 00:00:00 2001 From: erlendska Date: Wed, 28 Feb 2024 19:04:55 +0100 Subject: [PATCH 06/11] Final final changes --- inventory/templates/inventory/loan_apply.html | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/inventory/templates/inventory/loan_apply.html b/inventory/templates/inventory/loan_apply.html index 43b5f2db6..795227729 100644 --- a/inventory/templates/inventory/loan_apply.html +++ b/inventory/templates/inventory/loan_apply.html @@ -36,24 +36,24 @@

Lånesøknad - {{ item.name }}

Lånedetaljer
-
-
- date_range - {{ form.loan_from }} - - {{ form.loan_from.errors }} -
-
- date_range - {{ form.loan_to }} - - {{ form.loan_to.errors }} -
-
- {{ form.amount }} - - {{ form.amount.errors }} -
+
+ date_range + {{ form.loan_from }} + + {{ form.loan_from.errors }} +
+
+ date_range + {{ form.loan_to }} + + {{ form.loan_to.errors }} +
+
+ {{ form.amount }} + + {{ form.amount.errors }} +
+
{{ form.purpose }} {{ form.purpose.errors }} From 920c2b1be1f5ebbe3f6feaf37421d13eac771f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:48:09 +0100 Subject: [PATCH 07/11] update datepicker loan to on change --- inventory/static/inventory/js/loan_app.js | 71 ++++++++++--------- inventory/templates/inventory/loan_apply.html | 3 + inventory/views/item_loan.py | 4 -- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/inventory/static/inventory/js/loan_app.js b/inventory/static/inventory/js/loan_app.js index a3bdd9e88..8d5b53189 100644 --- a/inventory/static/inventory/js/loan_app.js +++ b/inventory/static/inventory/js/loan_app.js @@ -37,45 +37,50 @@ document.addEventListener("DOMContentLoaded", function() { weekdaysAbbrev: ['S','M','T','O','T','F','L'] } + const loanFromDate = document.getElementById('id_loan_from'); + options = { + format: 'dd.mm.yyyy', + firstDay: 1, + i18n: internationalization, + minDate: new Date(loanFromDate.value) + } + 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) + if (dp.id === 'id_loan_to') { + if (maxLoanDays) { + const maxDate = new Date() + maxDate.setDate(new Date(loanFromDate.value).getDate() + maxLoanDays) + options.maxDate = maxDate + } } M.Datepicker.init(dp, options); } - // 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]; + loanFromDate.addEventListener('change', () => { + updateLoanToDatepicker(options, maxLoanDays) + }); - if(reg_check.checked) { - reg_box.classList.remove('hide'); - ext_reg.classList.add('hide'); - } - else { - reg_box.classList.add('hide'); - ext_reg.classList.remove('hide'); - } +}); - 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 = ''; - } - }; +function parseFormattedDate(dateString) { + const dateParts = dateString.split('.'); + return new Date(dateParts[2], dateParts[1]-1, dateParts[0]); +} -}); +function updateLoanToDatepicker(datepickerOptions, maxLoanDays) { + const loanFromDateEl = document.getElementById('id_loan_from'); + const loanToDate = document.getElementById('id_loan_to'); + + const loanFromDate = parseFormattedDate(loanFromDateEl.value) + + datepickerOptions.minDate = loanFromDate + + if (maxLoanDays) { + const maxDate = new Date(loanFromDate) + maxDate.setDate(loanFromDate.getDate() + maxLoanDays) + datepickerOptions.maxDate = maxDate + } + + M.Datepicker.init(loanToDate, datepickerOptions); +} diff --git a/inventory/templates/inventory/loan_apply.html b/inventory/templates/inventory/loan_apply.html index 795227729..3c1e0a7df 100644 --- a/inventory/templates/inventory/loan_apply.html +++ b/inventory/templates/inventory/loan_apply.html @@ -115,6 +115,9 @@
Medlemsfordeler
+ {% endblock %} diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index e2754a491..62f4f250d 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -186,10 +186,6 @@ 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" return form From a2418f9737bc4298274e6b8629e4f4f7349e4cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:43:54 +0100 Subject: [PATCH 08/11] change format of date and enable max one month ahead --- inventory/static/inventory/js/loan_app.js | 49 ++++++++++--------- inventory/templates/inventory/loan_apply.html | 12 ++++- inventory/views/item_loan.py | 19 +++++-- 3 files changed, 53 insertions(+), 27 deletions(-) diff --git a/inventory/static/inventory/js/loan_app.js b/inventory/static/inventory/js/loan_app.js index 8d5b53189..2985250a8 100644 --- a/inventory/static/inventory/js/loan_app.js +++ b/inventory/static/inventory/js/loan_app.js @@ -37,28 +37,18 @@ document.addEventListener("DOMContentLoaded", function() { weekdaysAbbrev: ['S','M','T','O','T','F','L'] } - const loanFromDate = document.getElementById('id_loan_from'); + const loanFromDateEl = document.getElementById('id_loan_from'); + const loanToDateEl = document.getElementById('id_loan_to'); + options = { format: 'dd.mm.yyyy', firstDay: 1, - i18n: internationalization, - minDate: new Date(loanFromDate.value) - } - - for (dp of datepickers) { - if (dp.id === 'id_loan_to') { - if (maxLoanDays) { - const maxDate = new Date() - maxDate.setDate(new Date(loanFromDate.value).getDate() + maxLoanDays) - options.maxDate = maxDate - } - } - M.Datepicker.init(dp, options); + i18n: internationalization } - - loanFromDate.addEventListener('change', () => { - updateLoanToDatepicker(options, maxLoanDays) + initDatepickers(loanToDateEl, loanFromDateEl, maxLoanDays, loanFromMaxDate, options) + loanFromDateEl.addEventListener('change', () => { + updateLoanToDatepicker(loanToDateEl, loanFromDateEl, options, maxLoanDays) }); }); @@ -68,11 +58,26 @@ function parseFormattedDate(dateString) { return new Date(dateParts[2], dateParts[1]-1, dateParts[0]); } -function updateLoanToDatepicker(datepickerOptions, maxLoanDays) { - const loanFromDateEl = document.getElementById('id_loan_from'); - const loanToDate = document.getElementById('id_loan_to'); +function initDatepickers(loanToEl, loanFromEl, maxLoanDays, loanFromMaxDate, dpOptions) { + const toDateOptions = dpOptions + const fromDateOptions = { + ...toDateOptions, + } + + fromDateOptions.minDate = parseFormattedDate(loanFromEl.value); + if (loanFromMaxDate) { + fromDateOptions.maxDate = new Date(loanFromMaxDate); + } + console.log(fromDateOptions, toDateOptions) + + M.Datepicker.init(loanFromEl, fromDateOptions); + M.Datepicker.init(loanToEl, toDateOptions); + + updateLoanToDatepicker(loanToEl, loanFromEl, toDateOptions, maxLoanDays) +} - const loanFromDate = parseFormattedDate(loanFromDateEl.value) +function updateLoanToDatepicker(loanToEl, loanFromEl, datepickerOptions, maxLoanDays) { + const loanFromDate = parseFormattedDate(loanFromEl.value) datepickerOptions.minDate = loanFromDate @@ -82,5 +87,5 @@ function updateLoanToDatepicker(datepickerOptions, maxLoanDays) { datepickerOptions.maxDate = maxDate } - M.Datepicker.init(loanToDate, datepickerOptions); + M.Datepicker.init(loanToEl, datepickerOptions); } diff --git a/inventory/templates/inventory/loan_apply.html b/inventory/templates/inventory/loan_apply.html index 3c1e0a7df..e3a56a6ae 100644 --- a/inventory/templates/inventory/loan_apply.html +++ b/inventory/templates/inventory/loan_apply.html @@ -116,7 +116,17 @@
Medlemsfordeler
diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index 62f4f250d..725d812b6 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -1,5 +1,6 @@ from datetime import datetime, timedelta +from dateutil.relativedelta import relativedelta from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin from django.http import HttpResponseRedirect @@ -147,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 @@ -188,11 +190,17 @@ def get_form(self, *args, **kwargs): form = super().get_form(*args, **kwargs) 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"]) + loan_from_max_date = datetime.now() + relativedelta( + months=self.months_max_ahead + ) + context["loan_from_max_date"] = loan_from_max_date return context def form_valid(self, form): @@ -209,10 +217,11 @@ def form_valid(self, form): # 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.min.time() + 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[ @@ -227,10 +236,12 @@ def form_valid(self, form): "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 > datetime.now() + timedelta(days=14): + if loan_from_datetime > datetime.now() + relativedelta( + months=self.months_max_ahead + ): form.errors[ "loan_from" - ] = "Du kan ikke starte å låne denne gjenstanden mer enn 14 dager frem i tid" + ] = 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 From 7212081440c8dc706ee841ecbe4643b688104ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:10:41 +0100 Subject: [PATCH 09/11] set default as undefined --- inventory/static/inventory/js/loan_app.js | 3 --- inventory/templates/inventory/loan_apply.html | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/inventory/static/inventory/js/loan_app.js b/inventory/static/inventory/js/loan_app.js index 2985250a8..e58daef89 100644 --- a/inventory/static/inventory/js/loan_app.js +++ b/inventory/static/inventory/js/loan_app.js @@ -1,6 +1,4 @@ document.addEventListener("DOMContentLoaded", function() { - const datepickers = document.querySelectorAll('.datepicker'); - internationalization = { months: [ 'Januar', @@ -68,7 +66,6 @@ function initDatepickers(loanToEl, loanFromEl, maxLoanDays, loanFromMaxDate, dpO if (loanFromMaxDate) { fromDateOptions.maxDate = new Date(loanFromMaxDate); } - console.log(fromDateOptions, toDateOptions) M.Datepicker.init(loanFromEl, fromDateOptions); M.Datepicker.init(loanToEl, toDateOptions); diff --git a/inventory/templates/inventory/loan_apply.html b/inventory/templates/inventory/loan_apply.html index e3a56a6ae..c956fb4ed 100644 --- a/inventory/templates/inventory/loan_apply.html +++ b/inventory/templates/inventory/loan_apply.html @@ -116,11 +116,7 @@
Medlemsfordeler
diff --git a/inventory/views/item_loan.py b/inventory/views/item_loan.py index 725d812b6..a61f13579 100644 --- a/inventory/views/item_loan.py +++ b/inventory/views/item_loan.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import date, datetime, timedelta from dateutil.relativedelta import relativedelta from django.contrib import messages @@ -197,10 +197,9 @@ def get_form(self, *args, **kwargs): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["item"] = Item.objects.get(id=self.kwargs["pk"]) - loan_from_max_date = datetime.now() + relativedelta( + context["loan_from_max_date"] = date.today() + relativedelta( months=self.months_max_ahead ) - context["loan_from_max_date"] = loan_from_max_date return context def form_valid(self, form): @@ -236,8 +235,8 @@ def form_valid(self, form): "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 > datetime.now() + relativedelta( - months=self.months_max_ahead + if loan_from_datetime.date() > ( + date.today() + relativedelta(months=self.months_max_ahead) ): form.errors[ "loan_from"