Coverage for src/backend/InvenTree/part/migrations/0109_auto_20230517_1048.py: 21%

81 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 17:47 +0000

1# Generated by Django 3.2.19 on 2023-05-17 10:48 

2 

3import pint 

4 

5from django.core.exceptions import ValidationError 

6from django.db import migrations 

7 

8import InvenTree.conversion 

9 

10 

11def update_template_units(apps, schema_editor): 

12 """Update the units for each parameter template: 

13 

14 - Check if the units are valid 

15 - Attempt to convert to valid units (if possible) 

16 """ 

17 

18 PartParameterTemplate = apps.get_model('part', 'PartParameterTemplate') 

19 

20 n_templates = PartParameterTemplate.objects.count() 

21 

22 if n_templates == 0: 22 ↛ 26line 22 didn't jump to line 26 because the condition on line 22 was always true

23 # Escape early 

24 return 

25 

26 ureg = InvenTree.conversion.get_unit_registry() 

27 

28 n_converted = 0 

29 invalid_units = set() 

30 

31 for template in PartParameterTemplate.objects.all(): 

32 

33 # Skip empty units 

34 if not template.units: 

35 continue 

36 

37 # Override '%' units (which are invalid) 

38 if template.units == '%': 

39 template.units = 'percent' 

40 template.save() 

41 n_converted += 1 

42 continue 

43 

44 # Test if unit is 'valid' 

45 try: 

46 ureg.Unit(template.units) 

47 continue 

48 except Exception: 

49 pass 

50 

51 # Check a lower-case version 

52 try: 

53 ureg.Unit(template.units.lower()) 

54 print(f"Found unit match: {template.units} -> {template.units.lower()}") 

55 template.units = template.units.lower() 

56 template.save() 

57 n_converted += 1 

58 continue 

59 except Exception: 

60 pass 

61 

62 found = False 

63 

64 # Attempt to convert to a valid unit 

65 # Look for capitalization issues (e.g. "Ohm" -> "ohm") 

66 for unit in ureg: 

67 if unit.lower() == template.units.lower(): 

68 print(f"Found unit match: {template.units} -> {unit}") 

69 template.units = str(unit) 

70 template.save() 

71 n_converted += 1 

72 found = True 

73 break 

74 

75 if not found: 

76 print(f"warning: Could not find unit match for {template.units}") 

77 invalid_units.add(template.units) 

78 

79 print(f"Updated units for {n_templates} parameter templates") 

80 

81 if n_converted > 0: 

82 print(f" - Converted {n_converted} units") 

83 

84 if len(invalid_units) > 0: 

85 print(f" - Found {len(invalid_units)} invalid units:") 

86 

87 for unit in invalid_units: 

88 print(f" - {unit}") 

89 

90 

91 

92def convert_to_numeric_value(value: str, units: str): 

93 """Convert a value (with units) to a numeric value. 

94 

95 Defaults to zero if the value cannot be converted. 

96 """ 

97 

98 # Default value is null 

99 result = None 

100 

101 if units: 

102 try: 

103 result = InvenTree.conversion.convert_physical_value(value, units) 

104 result = float(result.magnitude) 

105 except Exception: 

106 pass 

107 else: 

108 try: 

109 result = float(value) 

110 except Exception: 

111 pass 

112 

113 return result 

114 

115 

116def update_parameter_values(apps, schema_editor): 

117 """Update the parameter values for all parts: 

118 

119 - Calculate the 'data_numeric' value for each parameter 

120 - If the template has invalid units, we'll ignore 

121 """ 

122 

123 PartParameter = apps.get_model('part', 'PartParameter') 

124 

125 n_params = PartParameter.objects.count() 

126 

127 # Convert each parameter value to a the specified units 

128 for parameter in PartParameter.objects.all(): 128 ↛ 129line 128 didn't jump to line 129 because the loop on line 128 never started

129 try: 

130 parameter.data_numeric = convert_to_numeric_value(parameter.data, parameter.template.units) 

131 parameter.save() 

132 except Exception: 

133 pass 

134 

135 if n_params > 0: 135 ↛ 136line 135 didn't jump to line 136 because the condition on line 135 was never true

136 print(f"Updated {n_params} parameter values") 

137 

138 

139class Migration(migrations.Migration): 

140 

141 atomic = False 

142 

143 dependencies = [ 

144 ('part', '0108_auto_20230516_1334'), 

145 ] 

146 

147 operations = [ 

148 migrations.RunPython( 

149 update_template_units, 

150 reverse_code=migrations.RunPython.noop 

151 ), 

152 migrations.RunPython( 

153 update_parameter_values, 

154 reverse_code=migrations.RunPython.noop 

155 ) 

156 ]