Coverage for src/backend/InvenTree/report/migrations/0026_auto_20240422_1301.py: 41%

61 statements  

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

1# Generated by Django 4.2.11 on 2024-04-22 13:01 

2 

3import os 

4 

5from django.core.files.base import ContentFile 

6from django.core.files.storage import default_storage 

7from django.db import connection, migrations 

8 

9import InvenTree.ready 

10 

11 

12def label_model_map(): 

13 """Map legacy label template models to model_type values.""" 

14 

15 return { 

16 "stockitemlabel": "stockitem", 

17 "stocklocationlabel": "stocklocation", 

18 "partlabel": "part", 

19 "buildlinelabel": "buildline", 

20 } 

21 

22 

23def convert_legacy_labels(table_name, model_name, template_model): 

24 """Map labels from an existing table to a new model type 

25  

26 Arguments: 

27 table_name: The name of the existing table 

28 model_name: The name of the new model type 

29 template_model: The model class for the new template model 

30  

31 Note: We use raw SQL queries here, as the original 'label' app has been removed entirely. 

32 """ 

33 count = 0 

34 

35 fields = [ 

36 'name', 'description', 'label', 'enabled', 'height', 'width', 'filename_pattern', 'filters' 

37 ] 

38 

39 non_null_fields = ['description', 'filename_pattern', 'filters'] 

40 

41 fieldnames = ', '.join(fields) 

42 

43 query = f"SELECT {fieldnames} FROM {table_name};" 

44 

45 with connection.cursor() as cursor: 

46 try: 

47 cursor.execute(query) 

48 except Exception: 

49 # Table likely does not exist - database was created more recently 

50 return 0 

51 

52 rows = cursor.fetchall() 

53 

54 for row in rows: 

55 data = { 

56 fields[idx]: row[idx] for idx in range(len(fields)) 

57 } 

58 

59 for field in non_null_fields: 

60 if data.get(field, None) is None: 

61 data[field] = '' 

62 

63 # Skip any "builtin" labels 

64 if 'label/inventree/' in data['label']: 

65 continue 

66 

67 print(f"Creating new LabelTemplate for {model_name} - {data['name']}") 

68 

69 if template_model.objects.filter(name=data['name'], model_type=model_name).exists(): 

70 print(f"LabelTemplate {data['name']} already exists for {model_name} - skipping") 

71 continue 

72 

73 

74 if not default_storage.exists(data['label']): 

75 print(f"Label template file {data['label']} does not exist - skipping") 

76 continue 

77 

78 # Create a new template file object 

79 filedata = default_storage.open(data['label']).read() 

80 filename = os.path.basename(data['label']) 

81 

82 # Remove the 'label' key from the data dictionary 

83 data.pop('label') 

84 

85 data['template'] = ContentFile(filedata, filename) 

86 data['model_type'] = model_name 

87 

88 template_model.objects.create(**data) 

89 

90 count += 1 

91 

92 return count 

93 

94 

95def forward(apps, schema_editor): 

96 """Run forwards migrations. 

97  

98 - Create a new LabelTemplate instance for each existing legacy label template. 

99 """ 

100 

101 LabelTemplate = apps.get_model('report', 'labeltemplate') 

102 

103 count = 0 

104 

105 for template_class, model_type in label_model_map().items(): 

106 

107 table_name = f'label_{template_class}' 

108 

109 count += convert_legacy_labels(table_name, model_type, LabelTemplate) or 0 

110 

111 if count > 0: 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true

112 print(f"Migrated {count} report templates to new LabelTemplate model.") 

113 

114def reverse(apps, schema_editor): 

115 """Run reverse migrations. 

116  

117 - Delete any LabelTemplate instances in the database 

118 """ 

119 

120 LabelTemplate = apps.get_model('report', 'labeltemplate') 

121 

122 n = LabelTemplate.objects.count() 

123 

124 if n > 0: 

125 for item in LabelTemplate.objects.all(): 

126 

127 item.template.delete() 

128 item.delete() 

129 

130 print(f"Deleted {n} LabelTemplate objects and templates") 

131 

132class Migration(migrations.Migration): 

133 

134 atomic = False 

135 

136 dependencies = [ 

137 ('report', '0025_labeltemplate'), 

138 ] 

139 

140 operations = [ 

141 migrations.RunPython(forward, reverse_code=reverse) 

142 ] 

143