diff --git a/src/genlab_bestilling/migrations/0020_sample_is_prioritised.py b/src/genlab_bestilling/migrations/0020_sample_is_prioritised.py index 3c431782..c9208b96 100644 --- a/src/genlab_bestilling/migrations/0020_sample_is_prioritised.py +++ b/src/genlab_bestilling/migrations/0020_sample_is_prioritised.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.3 on 2025-07-07 06:40 +# Generated by Django 5.2.3 on 2025-07-07 09:53 from django.db import migrations, models diff --git a/src/genlab_bestilling/migrations/0022_sample_internal_note.py b/src/genlab_bestilling/migrations/0022_sample_internal_note.py new file mode 100644 index 00000000..48249fe7 --- /dev/null +++ b/src/genlab_bestilling/migrations/0022_sample_internal_note.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-07-07 13:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("genlab_bestilling", "0021_order_is_prioritized_order_is_seen"), + ] + + operations = [ + migrations.AddField( + model_name="sample", + name="internal_note", + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/src/genlab_bestilling/models.py b/src/genlab_bestilling/models.py index cf094cc1..cbc645f0 100644 --- a/src/genlab_bestilling/models.py +++ b/src/genlab_bestilling/models.py @@ -634,6 +634,9 @@ class Sample(models.Model): species = models.ForeignKey(f"{an}.Species", on_delete=models.PROTECT) year = models.IntegerField() notes = models.TextField(null=True, blank=True) + + # "Merknad" in the Excel sheet. + internal_note = models.TextField(null=True, blank=True) pop_id = models.CharField(max_length=150, null=True, blank=True) location = models.ForeignKey( f"{an}.Location", on_delete=models.PROTECT, null=True, blank=True diff --git a/src/staff/tables.py b/src/staff/tables.py index 43066242..2f7f42a0 100644 --- a/src/staff/tables.py +++ b/src/staff/tables.py @@ -235,9 +235,14 @@ class CustomSampleTable(tables.Table): default=False, ) + internal_note = tables.TemplateColumn( + template_name="staff/note_input_column.html", orderable=False + ) + class Meta: model = Sample - fields = ["checked", "genlab_id"] + list(base_fields) + fields = ["checked", "genlab_id", "internal_note"] + list(base_fields) + sequence = ["checked", "genlab_id"] + list(base_fields) + ["internal_note"] return CustomSampleTable diff --git a/src/staff/templates/staff/note_input_column.html b/src/staff/templates/staff/note_input_column.html new file mode 100644 index 00000000..c98206c3 --- /dev/null +++ b/src/staff/templates/staff/note_input_column.html @@ -0,0 +1,7 @@ + diff --git a/src/staff/templates/staff/sample_lab.html b/src/staff/templates/staff/sample_lab.html index 6994df77..84752049 100644 --- a/src/staff/templates/staff/sample_lab.html +++ b/src/staff/templates/staff/sample_lab.html @@ -24,17 +24,37 @@

{% block page-title %}{% if order %}{{ order }} - Samp {% block body_javascript %} - -{% endblock body_javascript %} +{% endblock body_javascript%} diff --git a/src/staff/urls.py b/src/staff/urls.py index 46c8ba5a..07a7e696 100644 --- a/src/staff/urls.py +++ b/src/staff/urls.py @@ -27,6 +27,7 @@ SampleLabView, SampleReplicaActionView, SamplesListView, + UpdateLabViewFields, ) app_name = "staff" @@ -93,6 +94,11 @@ GenerateGenlabIDsView.as_view(), name="generate-genlab-ids", ), + path( + "orders/samples/update/", + UpdateLabViewFields.as_view(), + name="update-sample", + ), path( "orders/analysis//samples/", OrderAnalysisSamplesListView.as_view(), diff --git a/src/staff/views.py b/src/staff/views.py index 74229087..6bc92bca 100644 --- a/src/staff/views.py +++ b/src/staff/views.py @@ -6,7 +6,7 @@ from django.db import models from django.db.models import Count from django.forms import Form -from django.http import HttpRequest, HttpResponse, HttpResponseRedirect +from django.http import HttpRequest, HttpResponse, HttpResponseRedirect, JsonResponse from django.shortcuts import get_object_or_404 from django.urls import reverse, reverse_lazy from django.utils.timezone import now @@ -377,6 +377,27 @@ def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: return HttpResponseRedirect(self.get_success_url()) +class UpdateLabViewFields(StaffMixin, ActionView): + def post(self, request: HttpRequest, *args, **kwargs) -> JsonResponse: + sample_id = request.POST.get("sample_id") + field_name = request.POST.get("field_name") + field_value = request.POST.get("field_value") + + if not sample_id or not field_name or field_value is None: + return JsonResponse({"error": "Invalid input"}, status=400) + + try: + sample = Sample.objects.get(id=sample_id) + + if field_name == "internal_note-input": + sample.internal_note = field_value + sample.save() + + return JsonResponse({"success": True}) + except Sample.DoesNotExist: + return JsonResponse({"error": "Sample not found"}, status=404) + + class ManaullyCheckedOrderActionView(SingleObjectMixin, ActionView): model = ExtractionOrder