Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/genlab_bestilling/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class EquipmentOrderAdmin(ModelAdmin):
search_help_text = "Search for equipment name or id"
search_fields = [
EO.name.field.name,
EO.id.field.name,
EO.id.field.name, # type: ignore[attr-defined]
]
list_filter = [
(EO.sample_types.field.name, unfold_filters.AutocompleteSelectMultipleFilter),
Expand Down Expand Up @@ -320,7 +320,7 @@ class ExtractionOrderAdmin(ModelAdmin):
search_help_text = "Search for extraction name or id"
search_fields = [
EO.name.field.name,
EO.id.field.name,
EO.id.field.name, # type: ignore[attr-defined]
]
list_filter = [
(EO.species.field.name, unfold_filters.AutocompleteSelectMultipleFilter),
Expand Down
4 changes: 2 additions & 2 deletions src/genlab_bestilling/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_has_error(self, obj: Sample) -> bool:
try:
return obj.has_error
except exceptions.ValidationError as e:
return e.detail[0]
return e.detail[0] # type: ignore[return-value,index] # TODO: check if this is actually bool.

class Meta:
model = Sample
Expand Down Expand Up @@ -186,7 +186,7 @@ def get_has_error(self, obj: Sample) -> bool:
try:
return obj.has_error
except exceptions.ValidationError as e:
return e.detail[0]
return e.detail[0] # type: ignore[return-value,index] # TODO: check if this is actually bool.

class Meta:
model = Sample
Expand Down
3 changes: 2 additions & 1 deletion src/genlab_bestilling/api/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import contextlib
import re
import uuid
from typing import Any

from django.db import transaction
from django.db.models import QuerySet
Expand Down Expand Up @@ -104,7 +105,7 @@ def get_csv_fields_and_labels(
labels = [self.FIELD_LABELS.get(f, f) for f in fields]
return fields, labels

def get_nested(self, obj: dict, dotted: str) -> str | None:
def get_nested(self, obj: Any, dotted: str) -> Any:
for part in dotted.split("."):
obj = obj.get(part) if isinstance(obj, dict) else None
return obj
Expand Down
16 changes: 8 additions & 8 deletions src/genlab_bestilling/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, *args, user: User | None = None, project: Any = None, **kwarg
self.user = user

if "project" in self.fields:
self.fields[
self.fields[ # type: ignore[attr-defined]
"project"
].queryset = Project.objects.filter_selectable().filter(
memberships=user,
Expand Down Expand Up @@ -121,7 +121,7 @@ def __init__(self, *args, genrequest: Genrequest, **kwargs):
self.genrequest = genrequest

# self.fields["species"].queryset = genrequest.species.all()
self.fields["sample_types"].queryset = genrequest.sample_types.all()
self.fields["sample_types"].queryset = genrequest.sample_types.all() # type: ignore[attr-defined]

def save(self, commit: bool = True) -> EquipmentOrder:
obj = super().save(commit=False)
Expand Down Expand Up @@ -167,9 +167,9 @@ def save(self, commit: bool = True) -> EquipmentOrder:
return obj

def clean(self) -> None:
cleaned_data = super().clean()
cleaned_data = super().clean() or {}

if not cleaned_data["equipment"] and not cleaned_data["buffer"]:
if not cleaned_data.get("equipment") and not cleaned_data.get("buffer"):
msg = "Equipment and/or Buffer should be filled"
raise ValidationError(msg)

Expand Down Expand Up @@ -249,8 +249,8 @@ def __init__(self, *args, genrequest: Genrequest, **kwargs):
"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["species"].queryset = genrequest.species.all() # type: ignore[attr-defined]
self.fields["sample_types"].queryset = genrequest.sample_types.all() # type: ignore[attr-defined]
# self.fields["markers"].queryset = Marker.objects.filter(
# species__genrequests__id=genrequest.id
# ).distinct()
Expand Down Expand Up @@ -307,12 +307,12 @@ def __init__(self, *args, genrequest: Genrequest, **kwargs):
"for this order to help you find it later"
)

self.fields["markers"].queryset = Marker.objects.filter(
self.fields["markers"].queryset = Marker.objects.filter( # type: ignore[attr-defined]
genrequest__id=genrequest.id
).distinct()
self.fields["markers"].required = True
if "from_order" in self.fields:
self.fields["from_order"].queryset = ExtractionOrder.objects.filter(
self.fields["from_order"].queryset = ExtractionOrder.objects.filter( # type: ignore[attr-defined]
genrequest_id=genrequest.id,
).exclude(status=Order.OrderStatus.DRAFT)
self.fields["from_order"].help_text = (
Expand Down
4 changes: 3 additions & 1 deletion src/genlab_bestilling/libs/isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def isolate(order_id: int | str) -> None:
position = 0

ExtractPlatePosition.objects.create(
plate=plate, sample=sample, position=position
plate=plate,
sample=sample,
position=position, # type: ignore[misc]
)
position += 1
4 changes: 3 additions & 1 deletion src/genlab_bestilling/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from shared.db import assert_is_in_atomic_block

if TYPE_CHECKING:
from collections.abc import Sequence

from django.db.models import QuerySet

from capps.users.models import User
Expand Down Expand Up @@ -75,7 +77,7 @@ def filter_in_draft(self) -> QuerySet:
def generate_genlab_ids(
self,
order_id: int,
selected_samples: list[int] | None = None,
selected_samples: Sequence[int | str] | None = None,
) -> None:
"""
genlab ids given a certain order_id, sorting order and sample ids
Expand Down
16 changes: 13 additions & 3 deletions src/genlab_bestilling/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import uuid
from collections.abc import Sequence
from datetime import timedelta
from typing import Any

Expand Down Expand Up @@ -508,7 +509,7 @@ def confirm_order(self, persist: bool = True) -> None:
@transaction.atomic
def order_selected_checked(
self,
selected_samples: list[int] | None = None,
selected_samples: Sequence[int | str] | None = None,
) -> None:
"""
Partially set the order as checked by the lab staff,
Expand All @@ -522,7 +523,7 @@ def order_selected_checked(
return

Sample.objects.generate_genlab_ids(
order_id=self.id,
order_id=self.id, # type: ignore[arg-type] # `self` has been saved first, so id is known to exists.
selected_samples=selected_samples,
)

Expand Down Expand Up @@ -741,7 +742,7 @@ def has_error(self) -> bool:
):
msg = "Invalid location for the selected species"
raise ValidationError(msg)
elif self.location_id and self.species.location_type_id:
elif self.species.location_type_id and self.location:
# if the location is optional, but it's provided,
# check it is compatible with the species
if self.species.location_type_id not in self.location.types.values_list(
Expand All @@ -752,12 +753,21 @@ def has_error(self) -> bool:

return False

class MissingOrder(Exception):
"""
Exception raised when trying to generate a genlab_id without an ExtractionOrder.
"""

def generate_genlab_id(self, commit: bool = True) -> str:
assert_is_in_atomic_block()

if self.genlab_id:
return self.genlab_id
species = self.species

if not self.order:
raise self.MissingOrder

year = self.order.confirmed_at.year

sequence = GIDSequence.objects.get_sequence_for_species_year(
Expand Down
2 changes: 1 addition & 1 deletion src/nina/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def get_form_kwargs(self) -> dict[str, Any]:
def get_success_url(self) -> str:
return reverse(
"nina:project-detail",
kwargs={"pk": self.object.pk},
kwargs={"pk": self.object.pk}, # type: ignore[union-attr]
)


Expand Down
2 changes: 1 addition & 1 deletion src/shared/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(
bound_field_class=None,
**kwargs,
) -> None:
super().__init__(
super().__init__( # type: ignore[call-arg]
data=data,
files=files,
auto_id=auto_id,
Expand Down
2 changes: 1 addition & 1 deletion src/shared/sentry.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
def report_errors(err: Exception, app_name: str = __name__) -> None:
logger = logging.getLogger(app_name)

if settings.SENTRY_DSN:
if settings.SENTRY_DSN: # type: ignore[misc]
from sentry_sdk import capture_exception # noqa: PLC0415

capture_exception(err)
Expand Down
2 changes: 1 addition & 1 deletion src/staff/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class OrderStaffForm(forms.Form):
def __init__(self, *args, order: Order | Genrequest | None = None, **kwargs):
super().__init__(*args, **kwargs)

self.fields["responsible_staff"].choices = self.get_all_staff()
self.fields["responsible_staff"].choices = self.get_all_staff() # type: ignore[attr-defined]

if order:
self.fields["responsible_staff"].initial = [
Expand Down
4 changes: 2 additions & 2 deletions src/staff/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ class Meta(OrderTable.Meta):
"needs_guid",
"sample_types",
]
sequence = ("is_seen", "is_urgent", "status", "id", "name")
sequence = ["is_seen", "is_urgent", "status", "id", "name"]
empty_text = "No Orders"
order_by = ("-is_urgent", "last_modified_at", "created_at")
order_by = ["-is_urgent", "last_modified_at", "created_at"]

def render_id(self, record: Any) -> str:
return str(record)
Expand Down
38 changes: 22 additions & 16 deletions src/staff/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_template_names(self) -> list[str]:
]

def test_func(self) -> bool:
return self.request.user.is_superuser or self.request.user.is_genlab_staff()
return self.request.user.is_superuser or self.request.user.is_genlab_staff() # type: ignore[attr-defined]


class DashboardView(StaffMixin, TemplateView):
Expand Down Expand Up @@ -261,35 +261,41 @@ def get_return_url(self, return_to: str | None) -> str:
class ExtractionOrderDetailView(StaffMixin, DetailView):
model = ExtractionOrder

# Retrieves analysis orders associated with the samples in the extraction order
def get_analysis_orders_for_samples(
self, samples: QuerySet[Sample]
) -> QuerySet[AnalysisOrder]:
"""
Retrieves analysis orders associated with the samples in the extraction order.
"""
return AnalysisOrder.objects.filter(samples__in=samples).distinct()

# Checks if the analysis orders have multiple extraction orders
# This is used to determine which type of link to show in the template
def analysis_has_multiple_extraction_orders(
self, analysis_orders: QuerySet[AnalysisOrder]
self, *, analysis_orders: QuerySet[AnalysisOrder]
) -> bool:
if len(analysis_orders) == 1:
analysis_order = get_object_or_404(
AnalysisOrder, pk=analysis_orders.first().id
)
extraction_order_ids = analysis_order.samples.values_list(
"order_id", flat=True
).distinct()
return extraction_order_ids.count() > 1
return False
"""
Checks if the analysis orders have multiple extraction orders.
This is used to determine which type of link to show in the template.
"""
if analysis_orders.count() != 1:
return False

analysis_order = analysis_orders.first()

extraction_order_ids = analysis_order.samples.values_list( # type: ignore[union-attr] # We have already checked for existance.
"order_id", flat=True
).distinct()
return extraction_order_ids.count() > 1

def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
extraction_order = self.object
samples = extraction_order.samples.all()
analysis_orders = self.get_analysis_orders_for_samples(samples)
analysis_orders = self.get_analysis_orders_for_samples(samples=samples)
context["analysis_orders"] = analysis_orders
context["analysis_has_multiple_extraction_orders"] = (
self.analysis_has_multiple_extraction_orders(analysis_orders)
self.analysis_has_multiple_extraction_orders(
analysis_orders=analysis_orders
)
)
return context

Expand Down