Coverage for backend/django/core/auxiliary/methods/copy_flowsheet/copy_formulas.py: 88%

22 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-06-23 21:51 +0000

1from typing import List 

2 

3from core.auxiliary.formula_limits import validate_formula_length 

4from core.auxiliary.models.PropertyValue import PropertyValue 

5 

6from .copy_caching import ModelLookupDict 

7from ..replace_expression_ids import ( 

8 extract_id_from_formula_key, 

9 get_formula_keys, 

10 replace_props, 

11) 

12 

13 

14def update_formulas(model_lookups: ModelLookupDict, allow_not_found: bool = False) -> None: 

15 """ 

16 Each expression references the property values by their primary key. 

17 This is called after the property values have been updated, 

18 so that we can update their formulas to reference the new property values. 

19 

20 If `allow_not_found` is true, any formula reference that points to a 

21 property value outside the copied subset is left unchanged. This is useful 

22 for subset copies such as simulation-object duplication, where a formula may 

23 intentionally still reference an original property value. 

24 """ 

25 property_values = model_lookups.get(PropertyValue) 

26 if property_values is None: 

27 return 

28 for property_value in property_values: 

29 if property_value.formula: 

30 formula_keys = get_formula_keys(property_value.formula) 

31 # example formula key: prop_500 

32 formula_ids = [extract_id_from_formula_key(key) for key in formula_keys] 

33 # list of ids 

34 

35 if not allow_not_found: 35 ↛ 45line 35 didn't jump to line 45 because the condition on line 35 was always true

36 new_property_values: List[PropertyValue] = [ 

37 property_values.get_model(pk) for pk in formula_ids 

38 ] 

39 if None in new_property_values: 39 ↛ 42line 39 didn't jump to line 42 because the condition on line 39 was never true

40 

41 # Gracefully handle the case where a formula key does not match any property value. 

42 property_value.formula = "Failed to copy formula, could not find property in flowsheet." 

43 continue 

44 # otherwise, any none values will be replaced with the original formula key. 

45 new_formula_ids = [ 

46 property_values.get_model(pk).pk # get the new id 

47 if property_values.get_model(pk) is not None 

48 else pk # retain the original id  

49 for pk in formula_ids 

50 ] 

51 new_formula_props = [f"prop{pk}" for pk in new_formula_ids] 

52 property_value.formula = validate_formula_length( 

53 replace_props(property_value.formula, new_formula_props) 

54 ) 

55 

56 # We need to use the unsafe manager here, because the normal manager is blocked by access control 

57 PropertyValue._unsafe_objects.bulk_update(property_values, ["formula"])