2026-04-24 17:40:25 +03:30
|
|
|
from django.db import models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationScenario(models.Model):
|
|
|
|
|
class ScenarioType(models.TextChoices):
|
|
|
|
|
SINGLE = "single", "Single Simulation"
|
|
|
|
|
CROP_COMPARISON = "crop_comparison", "Crop Comparison"
|
|
|
|
|
FERTILIZATION_COMPARISON = (
|
|
|
|
|
"fertilization_comparison",
|
|
|
|
|
"Fertilization Comparison",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class Status(models.TextChoices):
|
|
|
|
|
PENDING = "pending", "Pending"
|
|
|
|
|
RUNNING = "running", "Running"
|
|
|
|
|
SUCCESS = "success", "Success"
|
|
|
|
|
FAILURE = "failure", "Failure"
|
|
|
|
|
|
|
|
|
|
name = models.CharField(max_length=255, blank=True, default="")
|
|
|
|
|
scenario_type = models.CharField(
|
|
|
|
|
max_length=64,
|
|
|
|
|
choices=ScenarioType.choices,
|
|
|
|
|
default=ScenarioType.SINGLE,
|
|
|
|
|
db_index=True,
|
|
|
|
|
)
|
2026-04-24 22:20:15 +03:30
|
|
|
model_name = models.CharField(max_length=128, default="Wofost81_NWLP_CWB_CNB")
|
2026-04-24 17:40:25 +03:30
|
|
|
status = models.CharField(
|
|
|
|
|
max_length=32,
|
|
|
|
|
choices=Status.choices,
|
|
|
|
|
default=Status.PENDING,
|
|
|
|
|
db_index=True,
|
|
|
|
|
)
|
|
|
|
|
input_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
result_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
error_message = models.TextField(blank=True, default="")
|
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
|
|
|
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ["-created_at"]
|
|
|
|
|
verbose_name = "Simulation Scenario"
|
|
|
|
|
verbose_name_plural = "Simulation Scenarios"
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name or f"{self.scenario_type}:{self.pk}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SimulationRun(models.Model):
|
|
|
|
|
scenario = models.ForeignKey(
|
|
|
|
|
SimulationScenario,
|
|
|
|
|
on_delete=models.CASCADE,
|
|
|
|
|
related_name="runs",
|
|
|
|
|
)
|
|
|
|
|
run_key = models.CharField(max_length=64)
|
|
|
|
|
label = models.CharField(max_length=255)
|
|
|
|
|
status = models.CharField(
|
|
|
|
|
max_length=32,
|
|
|
|
|
choices=SimulationScenario.Status.choices,
|
|
|
|
|
default=SimulationScenario.Status.PENDING,
|
|
|
|
|
db_index=True,
|
|
|
|
|
)
|
|
|
|
|
weather_payload = models.JSONField(default=list, blank=True)
|
|
|
|
|
soil_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
crop_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
site_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
agromanagement_payload = models.JSONField(default=list, blank=True)
|
|
|
|
|
result_payload = models.JSONField(default=dict, blank=True)
|
|
|
|
|
error_message = models.TextField(blank=True, default="")
|
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
|
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
ordering = ["scenario_id", "id"]
|
|
|
|
|
constraints = [
|
|
|
|
|
models.UniqueConstraint(
|
|
|
|
|
fields=["scenario", "run_key"],
|
|
|
|
|
name="crop_simulation_unique_run_key_per_scenario",
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
verbose_name = "Simulation Run"
|
|
|
|
|
verbose_name_plural = "Simulation Runs"
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.scenario_id}:{self.run_key}"
|