From b63a04fceb382340f85d8b98adffa37030dcd521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Cant=C3=B9?= Date: Fri, 13 Dec 2024 13:25:30 +0100 Subject: [PATCH] changes to models, timerange analysis, helpers text --- src/genlab_bestilling/forms.py | 43 +++++++++++-- ...isorder_expected_total_samples_and_more.py | 63 +++++++++++++++++++ src/genlab_bestilling/models.py | 37 +++++++++-- 3 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 src/genlab_bestilling/migrations/0013_remove_analysisorder_expected_total_samples_and_more.py diff --git a/src/genlab_bestilling/forms.py b/src/genlab_bestilling/forms.py index e69ff07..cabea61 100644 --- a/src/genlab_bestilling/forms.py +++ b/src/genlab_bestilling/forms.py @@ -2,6 +2,7 @@ from typing import Any from django import forms +from django.contrib.postgres.forms.ranges import RangeWidget # from django.core.exceptions import ValidationError from django.forms.renderers import BaseRenderer @@ -22,6 +23,10 @@ ) +class DateInput(forms.DateInput): + input_type = "date" + + class GenrequestForm(FormMixin, forms.ModelForm): default_renderer = FormRenderer(field_css_classes="mb-3") @@ -53,7 +58,8 @@ class Meta: "samples_owner", "sample_types", "analysis_types", - # "analysis_timerange", + "expected_total_samples", + "analysis_timerange", ) widgets = { "area": Selectize(search_lookup="name_icontains"), @@ -66,7 +72,7 @@ class Meta: ), "sample_types": DualSortableSelector(search_lookup="name_icontains"), "analysis_types": DualSortableSelector(search_lookup="name_icontains"), - # "analysis_timerange": DateRangePicker(), + "analysis_timerange": RangeWidget(DateInput), } @@ -77,7 +83,8 @@ class Meta(GenrequestForm.Meta): "species", "sample_types", "analysis_types", - # "analysis_timerange", + "analysis_timerange", + "expected_total_samples", ) # def clean_species(self) -> dict[str, Any]: @@ -199,13 +206,42 @@ def update_holder_instances(self, name, holder): holder.reinit(self.context) +YES_NO_CHOICES = ((False, "No"), (True, "Yes")) + + class AnalysisOrderForm(FormMixin, forms.ModelForm): default_renderer = FormRenderer(field_css_classes="mb-3") + needs_guid = forms.TypedChoiceField( + label="I need to generate GUID", + help_text="Choose yes if your samples don't have already a GUID, " + + "the system will generate a new GUID", + coerce=lambda x: x == "True", + choices=YES_NO_CHOICES, + widget=forms.RadioSelect, + ) + isolate_samples = forms.TypedChoiceField( + label="I want samples to be isolated", + coerce=lambda x: x == "True", + choices=YES_NO_CHOICES, + widget=forms.RadioSelect, + ) + return_samples = forms.TypedChoiceField( + label="I want samples to be returned after analysis", + coerce=lambda x: x == "True", + choices=YES_NO_CHOICES, + widget=forms.RadioSelect, + ) + def __init__(self, *args, genrequest, **kwargs): super().__init__(*args, **kwargs) self.genrequest = genrequest + self.fields["name"].help_text = ( + "You can provide a descriptive name " + + "for this order to help you find it later" + ) + self.fields["species"].queryset = genrequest.species.all() self.fields["sample_types"].queryset = genrequest.sample_types.all() self.fields["markers"].queryset = Marker.objects.filter( @@ -232,7 +268,6 @@ class Meta: "isolate_samples", "markers", "return_samples", - "expected_total_samples", ) widgets = { "species": DualSortableSelector( diff --git a/src/genlab_bestilling/migrations/0013_remove_analysisorder_expected_total_samples_and_more.py b/src/genlab_bestilling/migrations/0013_remove_analysisorder_expected_total_samples_and_more.py new file mode 100644 index 0000000..2e9f6ef --- /dev/null +++ b/src/genlab_bestilling/migrations/0013_remove_analysisorder_expected_total_samples_and_more.py @@ -0,0 +1,63 @@ +# Generated by Django 5.1.3 on 2024-12-13 08:23 + +import django.contrib.postgres.fields.ranges +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("genlab_bestilling", "0012_sample_unique_genlab_id"), + ("nina", "0001_initial"), + ] + + operations = [ + migrations.RemoveField( + model_name="analysisorder", + name="expected_total_samples", + ), + migrations.AddField( + model_name="genrequest", + name="expected_total_samples", + field=models.IntegerField( + blank=True, + help_text="This helps the Lab estimating the workload, provide how many samples you're going to deliver", + null=True, + ), + ), + migrations.AlterField( + model_name="genrequest", + name="analysis_timerange", + field=django.contrib.postgres.fields.ranges.DateRangeField( + blank=True, + help_text="This helps the Lab estimating the workload, provide the timeframe for the analysis", + null=True, + ), + ), + migrations.AlterField( + model_name="genrequest", + name="name", + field=models.CharField( + blank=True, max_length=255, null=True, verbose_name="Description" + ), + ), + migrations.AlterField( + model_name="genrequest", + name="project", + field=models.ForeignKey( + help_text="Choose the UBW NINA Project for billing", + on_delete=django.db.models.deletion.PROTECT, + to="nina.project", + verbose_name="UBW Project Name", + ), + ), + migrations.AlterField( + model_name="genrequest", + name="sample_types", + field=models.ManyToManyField( + blank=True, + help_text="samples you plan to deliver, you can choose more than one. ONLY sample types selected here will be available later", + to="genlab_bestilling.sampletype", + ), + ), + ] diff --git a/src/genlab_bestilling/models.py b/src/genlab_bestilling/models.py index b3e0034..e161b16 100644 --- a/src/genlab_bestilling/models.py +++ b/src/genlab_bestilling/models.py @@ -104,10 +104,20 @@ class Genrequest(models.Model): A GenLab genrequest, multiple GenLab requests can have the same NINA project number """ - name = models.CharField(max_length=255, null=True, blank=True) - project = models.ForeignKey("nina.Project", on_delete=models.PROTECT) + name = models.CharField( + max_length=255, null=True, blank=True, verbose_name="Description" + ) + project = models.ForeignKey( + "nina.Project", + on_delete=models.PROTECT, + verbose_name="UBW Project Name", + help_text="Choose the UBW NINA Project for billing", + ) samples_owner = models.ForeignKey( - "Organization", on_delete=models.PROTECT, blank=True, null=True + "Organization", + on_delete=models.PROTECT, + blank=True, + null=True, ) creator = models.ForeignKey( "users.User", @@ -118,9 +128,25 @@ class Genrequest(models.Model): ) area = models.ForeignKey("Area", on_delete=models.PROTECT) species = models.ManyToManyField("Species", blank=True, related_name="genrequests") - sample_types = models.ManyToManyField("SampleType", blank=True) + sample_types = models.ManyToManyField( + "SampleType", + blank=True, + help_text="samples you plan to deliver, you can choose more than one. " + + "ONLY sample types selected here will be available later", + ) analysis_types = models.ManyToManyField("AnalysisType", blank=True) - analysis_timerange = DateRangeField(null=True, blank=True) + analysis_timerange = DateRangeField( + null=True, + blank=True, + help_text="This helps the Lab estimating the workload, " + + "provide the timeframe for the analysis", + ) + expected_total_samples = models.IntegerField( + null=True, + blank=True, + help_text="This helps the Lab estimating the workload, " + + "provide how many samples you're going to deliver", + ) created_at = models.DateTimeField(auto_now_add=True) last_modified_at = models.DateTimeField(auto_now=True) @@ -244,7 +270,6 @@ class AnalysisOrder(Order): isolate_samples = models.BooleanField() # TODO: default? markers = models.ManyToManyField("Marker", blank=True, related_name="orders") return_samples = models.BooleanField() # TODO: default? - expected_total_samples = models.IntegerField(null=True, blank=True) def __str__(self) -> str: return f"#ANL_{self.id}"