Coverage for backend/django/flowsheetInternals/graphicData/models/portAnchorPlacementModel.py: 100%

25 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-07-22 05:22 +0000

1from typing import TYPE_CHECKING 

2from django.db import models 

3 

4from core.auxiliary.enums import AnchorSide 

5from core.managers import AccessControlManager, AllFlowsheetStatesManager 

6from core.auxiliary.models.FlowsheetHistoryModel import FlowsheetHistoryModel 

7 

8if TYPE_CHECKING: 

9 from core.auxiliary.models.Flowsheet import Flowsheet 

10 from flowsheetInternals.graphicData.models.graphicObjectModel import GraphicObject 

11 from flowsheetInternals.graphicData.models.groupingModel import Grouping 

12 from flowsheetInternals.unitops.models.Port import Port 

13 

14 

15class PortAnchorPlacement(FlowsheetHistoryModel, models.Model): 

16 """ 

17 Stores the visual anchor for one rendered occurrence of a port. 

18 

19 A port can be rendered directly on its owning unit operation, or on a group 

20 boundary that represents the hidden unit operation. These placements must be 

21 independent so moving a group-boundary anchor does not move the internal port. 

22 """ 

23 

24 class EndpointKind(models.TextChoices): 

25 UnitOperation = "unit_operation", "Unit operation" 

26 GroupBoundary = "group_boundary", "Group boundary" 

27 

28 flowsheet_state = models.ForeignKey( 

29 "core_auxiliary.FlowsheetState", 

30 on_delete=models.CASCADE, 

31 related_name="PortAnchorPlacements", 

32 ) 

33 port = models.ForeignKey( 

34 "flowsheetInternals_unitops.Port", 

35 on_delete=models.CASCADE, 

36 related_name="anchorPlacements", 

37 ) 

38 grouping = models.ForeignKey( 

39 "flowsheetInternals_graphicData.Grouping", 

40 on_delete=models.CASCADE, 

41 related_name="portAnchorPlacements", 

42 ) 

43 graphicObject = models.ForeignKey( 

44 "flowsheetInternals_graphicData.GraphicObject", 

45 on_delete=models.CASCADE, 

46 related_name="portAnchorPlacements", 

47 ) 

48 endpointKind = models.CharField(choices=EndpointKind.choices, max_length=32) 

49 anchor_side = models.CharField( 

50 choices=AnchorSide.choices, max_length=16, null=True, blank=True 

51 ) 

52 anchor_index = models.IntegerField(null=True, blank=True) 

53 created_at = models.DateTimeField(auto_now_add=True) 

54 

55 objects = AccessControlManager() 

56 all_states = AllFlowsheetStatesManager() 

57 

58 # runtime-accessed relations 

59 flowsheet: "Flowsheet" 

60 port: "Port" 

61 grouping: "Grouping" 

62 graphicObject: "GraphicObject" 

63 

64 class Meta: 

65 constraints = [ 

66 models.UniqueConstraint( 

67 fields=["port", "grouping", "graphicObject", "endpointKind"], 

68 name="unique_port_anchor_placement", 

69 ) 

70 ]