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
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ ignore = [
"ANN003", # Too strict for introduction of ANN. # https://docs.astral.sh/ruff/rules/missing-type-kwargs/
"ANN204", # Too strict for introduction of ANN. # https://docs.astral.sh/ruff/rules/missing-return-type-special-method/
"ANN401", # Too strict and too many errors atm. Consider enabling later after more typing is added. Search for `Any` to find unknown types. # https://docs.astral.sh/ruff/rules/any-type/
"TRY003" # This doesn't seem too bad. # https://docs.astral.sh/ruff/rules/raise-vanilla-args/
"TRY003", # This doesn't seem too bad. # https://docs.astral.sh/ruff/rules/raise-vanilla-args/
"DJ001" # Nullable string fields does is used a lot in this project. Maybe enable later? # https://docs.astral.sh/ruff/rules/django-nullable-model-string-field/
]
select = ["E", "W", "I", "F", "UP", "S", "B", "A", "COM", "LOG", "PTH", "Q", "PL", "RUF", "ANN", "PIE", "TC", "TRY"]
select = ["E", "W", "I", "F", "UP", "S", "B", "A", "COM", "LOG", "PTH", "Q", "PL", "RUF", "ANN", "PIE", "TC", "TRY", "DJ"]

[tool.ruff.lint.flake8-annotations]
mypy-init-return = true # https://docs.astral.sh/ruff/settings/#lint_flake8-annotations_mypy-init-return
Expand Down
79 changes: 41 additions & 38 deletions src/genlab_bestilling/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import uuid
from datetime import timedelta
from typing import TYPE_CHECKING, Any
from typing import Any

from django.conf import settings
from django.db import models, transaction
Expand All @@ -13,48 +13,45 @@

from shared.db import assert_is_in_atomic_block

if TYPE_CHECKING:
from .models import Sample

from . import managers
from .libs.helpers import position_to_coordinates

an = "genlab_bestilling" # Short alias for app name.


class Organization(models.Model):
name = models.CharField(max_length=255)

# TODO: unique name
def __str__(self) -> str:
return self.name
name = models.CharField(max_length=255)

class Meta:
ordering = ["name"]

def __str__(self) -> str:
return self.name


class Area(models.Model):
name = models.CharField(max_length=255)
location_mandatory = models.BooleanField(default=False)

class Meta:
ordering = ["name"]

# TODO: unique name
def __str__(self) -> str:
return self.name

class Meta:
ordering = ["name"]


class Marker(models.Model):
name = models.CharField(primary_key=True)
analysis_type = models.ForeignKey(f"{an}.AnalysisType", on_delete=models.DO_NOTHING)

def __str__(self) -> str:
return self.name

class Meta:
ordering = ["name"]

def __str__(self) -> str:
return self.name


class Species(models.Model):
name = models.CharField(max_length=255)
Expand All @@ -69,21 +66,24 @@ class Species(models.Model):
)
code = models.CharField(null=True, blank=True)

def __str__(self) -> str:
return self.name

class Meta:
verbose_name_plural = "Species"
ordering = ["name"]
constraints = [
models.UniqueConstraint(name="unique species code", fields=["code"])
]

def __str__(self) -> str:
return self.name


class SampleType(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)
areas = models.ManyToManyField(f"{an}.Area", blank=True)

class Meta:
ordering = ["name"]

def __str__(self) -> str:
return self.name or ""

Expand All @@ -95,13 +95,13 @@ def konciv_id(self) -> str:
def konciv_type(self) -> str:
return "SAMPLE_TYPE"

class Meta:
ordering = ["name"]


class AnalysisType(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)

class Meta:
ordering = ["name"]

def __str__(self) -> str:
return self.name or ""

Expand All @@ -113,9 +113,6 @@ def konciv_id(self) -> str:
def konciv_type(self) -> str:
return "ANALYSIS_TYPE"

class Meta:
ordering = ["name"]


class LocationType(models.Model):
name = models.CharField(max_length=250)
Expand Down Expand Up @@ -216,18 +213,21 @@ class Genrequest(models.Model): # type: ignore[django-manager-missing]
objects = managers.GenrequestQuerySet.as_manager()
tags = TaggableManager(blank=True)

class Meta:
verbose_name = "Genetic Project"

def __str__(self):
return f"#GEN_{self.id} ({self.project})"

def display_id(self) -> str:
return f"#GEN_{self.id}"

def get_absolute_url(self) -> str:
return reverse(
"genrequest-detail",
kwargs={"pk": self.pk},
)

def display_id(self) -> str:
return f"#GEN_{self.id}"

def get_type(self) -> str:
return "genrequest"

Expand All @@ -237,9 +237,6 @@ def short_timeframe(self) -> bool:
self.expected_analysis_delivery_date - self.expected_samples_delivery_date
) < timedelta(days=30)

class Meta:
verbose_name = "Genetic Project"


class Order(PolymorphicModel):
class CannotConfirm(ValidationError):
Expand Down Expand Up @@ -416,6 +413,9 @@ class EquimentOrderQuantity(models.Model):
class Meta:
verbose_name_plural = "Equipment order quantities"

def __str__(self) -> str:
return f"{self.quantity}"


class EquipmentOrder(Order):
needs_guid = models.BooleanField() # TODO: default?
Expand Down Expand Up @@ -615,6 +615,8 @@ class SampleMarkerAnalysis(models.Model):
marker = models.ForeignKey(f"{an}.Marker", on_delete=models.PROTECT)
transaction = models.UUIDField(blank=True, null=True)

objects = managers.SampleAnalysisMarkerQuerySet.as_manager()

class Meta:
verbose_name_plural = "Sample marker analyses"
constraints = [
Expand All @@ -624,8 +626,6 @@ class Meta:
)
]

objects = managers.SampleAnalysisMarkerQuerySet.as_manager()

def __str__(self):
return f"{str(self.sample)} {str(self.marker)} @ {str(self.order)}"

Expand Down Expand Up @@ -671,20 +671,20 @@ class Sample(models.Model):
help_text="The isolation method used for this sample",
)

objects = managers.SampleQuerySet.as_manager()
is_prioritised = models.BooleanField(
default=False,
help_text="Check this box if the sample is prioritised for processing",
)

def __str__(self) -> str:
return self.genlab_id or f"#SMP_{self.id}"
objects = managers.SampleQuerySet.as_manager()

class Meta:
constraints = [
models.UniqueConstraint(fields=["genlab_id"], name="unique_genlab_id")
]

def __str__(self) -> str:
return self.genlab_id or f"#SMP_{self.id}"

def create_replica(self) -> None:
pk = self.id
self.id = None
Expand Down Expand Up @@ -797,6 +797,9 @@ class SampleIsolationMethod(models.Model):
class Meta:
unique_together = ("sample", "isolation_method")

def __str__(self) -> str:
return f"{self.sample} - {self.isolation_method}"


class IsolationMethod(models.Model):
name = models.CharField(max_length=255, unique=False)
Expand Down Expand Up @@ -896,8 +899,7 @@ class GIDSequence(models.Model):
related_name="replica_sequence",
)

def __str__(self):
return f"{self.id}@{self.last_value}"
objects = managers.GIDSequenceQuerySet.as_manager()

class Meta:
constraints = [
Expand All @@ -906,7 +908,8 @@ class Meta:
),
]

objects = managers.GIDSequenceQuerySet.as_manager()
def __str__(self):
return f"{self.id}@{self.last_value}"

def next_value(self) -> str:
"""
Expand Down