Coverage for backend/django/flowsheetInternals/unitops/serializers/SimulationObjectSerializer.py: 93%
67 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from core.serializer_base import StateOwnedModelSerializer
2from core.validation import get_current_flowsheet
3from core.auxiliary.models.Flowsheet import Flowsheet
4from rest_framework import serializers
5from flowsheetInternals.unitops.models.property_package_propogation import (
6 propogate_property_package,
7)
8from flowsheetInternals.unitops.models import SimulationObject, SimulationObjectFactory
9from flowsheetInternals.propertyPackages.models.StreamFactory import StreamFactory
10from core.auxiliary.serializers.PropertyInfoSerializer import PropertySetSerializer
13class SimulationObjectSerializer(StateOwnedModelSerializer):
14 componentName = serializers.CharField(required=False, allow_blank=True, default="")
15 # The x and y coordinates of the unit operation.
16 x = serializers.DecimalField(
17 max_digits=10, decimal_places=5, write_only=True, default=0.0
18 )
19 y = serializers.DecimalField(
20 max_digits=10, decimal_places=5, write_only=True, default=0.0
21 )
22 parentGroup = serializers.IntegerField(
23 write_only=True, default=0
24 ) # initial group to add the simulation object to
25 propertySetId = serializers.PrimaryKeyRelatedField(
26 source="properties.pk", read_only=True
27 )
28 groupId = serializers.PrimaryKeyRelatedField(
29 source="grouping.pk", read_only=True
30 ) # This group id is only present on Group unit operations. see groupingModel.py
31 unspecifiedProperties = serializers.SerializerMethodField()
33 class Meta:
34 model = SimulationObject
35 extra_kwargs = {
36 "componentName": {"required": False}, # auto-generated
37 }
38 fields = "__all__"
40 def create(self, validated_data):
41 context = get_current_flowsheet() or {}
42 flowsheet_id = context.get("flowsheet")
43 flowsheet_state_id = context.get("flowsheet_state")
44 if flowsheet_id is None or flowsheet_state_id is None: 44 ↛ 45line 44 didn't jump to line 45 because the condition on line 44 was never true
45 raise serializers.ValidationError(
46 "An active flowsheet context is required to create a simulation object."
47 )
49 # The public ``flowsheet`` field validates stable identity but is not a
50 # model field, so it is deliberately absent from ``validated_data``.
51 # Rehydrate the captured stable/state pair for the factory so naming,
52 # root-group placement, and all related rows use this request's state.
53 try:
54 flowsheet = Flowsheet.objects.select_related("current_state").get(
55 pk=flowsheet_id,
56 current_state_id=flowsheet_state_id,
57 )
58 except Flowsheet.DoesNotExist as exc:
59 raise serializers.ValidationError(
60 "The active flowsheet state is no longer current."
61 ) from exc
63 x = float(validated_data.pop("x"))
64 y = float(validated_data.pop("y"))
65 coordinates = {"x": x, "y": y}
66 result = SimulationObjectFactory.create_simulation_object(
67 coordinates,
68 flowsheet=flowsheet,
69 **validated_data,
70 )
71 result.flowsheet_state.flowsheet.record_content_change()
72 return result
74 def to_representation(self, instance):
75 """Include the canvas context needed to faithfully replay creation."""
77 representation = super().to_representation(instance)
78 graphic = instance.graphicObject.first()
79 if graphic is not None: 79 ↛ 83line 79 didn't jump to line 83 because the condition on line 79 was always true
80 representation["x"] = f"{graphic.x + graphic.width / 2:.5f}"
81 representation["y"] = f"{graphic.y + graphic.height / 2:.5f}"
82 representation["parentGroup"] = graphic.group_id
83 return representation
85 def save(self, **kwargs):
86 # Update property package
87 validated_data = self.validated_data
88 result = super().save(**kwargs)
89 # Then propagate it to all connected streams
90 if (
91 validated_data.get("propertyPackageType") is not None
92 or validated_data.get("customPackage") is not None
93 ):
94 if (
95 self.instance.objectType == "stream"
96 or self.instance.objectType == "humid_air_stream"
97 ):
98 factory = StreamFactory(self.instance)
99 factory.check_and_update_stream()
100 propogate_property_package(self.instance)
101 self.instance.flowsheet_state.flowsheet.record_content_change()
103 return result
105 def get_unspecifiedProperties(self, instance: SimulationObject) -> list:
106 return instance.get_unspecified_properties()
109class SimulationObjectRetrieveSerializer(StateOwnedModelSerializer):
110 properties = PropertySetSerializer(read_only=True)
111 propertySetId = serializers.PrimaryKeyRelatedField(
112 source="properties.pk",
113 read_only=True,
114 )
115 # This group id is only present on Group unit operations. see groupingModel.py
116 groupId = serializers.PrimaryKeyRelatedField(
117 source="grouping.pk",
118 read_only=True,
119 )
120 unspecifiedProperties = serializers.SerializerMethodField()
122 class Meta:
123 model = SimulationObject
124 fields = "__all__"
125 extra_kwargs = {
126 "componentName": {"required": False}, # auto-generated
127 }
129 def get_unspecifiedProperties(self, instance: SimulationObject) -> list:
130 return instance.get_unspecified_properties()