-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfix_categories.py
More file actions
138 lines (130 loc) · 4.64 KB
/
Copy pathfix_categories.py
File metadata and controls
138 lines (130 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""
Fix category parent relationships.
Run: python fix_categories.py
"""
import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
django.setup()
from apps.consumables.models import ConsumableCategory
print("Fixing category parent relationships...\n")
# Define the correct structure
structure = {
"Epson L6190 Printer ink bottle": [
"Epson 001 Black ink bottle",
"Epson 001 Cyan ink bottle",
"Epson 001 Magenta ink bottle",
"Epson 001 Yellow ink bottle",
"Epson L6190 Maintenance Box",
],
"Epson L6460 / L6490 ink bottle": [
"Epson 008 Black ink bottle (C13T06G198)",
"Epson 008 Cyan ink bottle (C13T06G298)",
"Epson 008 Magenta ink bottle (C13T06G398)",
"Epson 008 Yellow ink bottle (C13T06G498)",
],
"Canon CL-746 Ink Cartridge": [
"Canon CL-746 Colour Ink Cartridge",
"Canon PG-745 Black Ink Cartridge",
"Canon PG-745XL Black Ink Cartridge (High Yield)",
],
"HP Toner Cartridge": [
"HP 85A Black Toner (CE285A)",
"HP 12A Black Toner (Q2612A)",
"HP 88A Black Toner (CC388A)",
"HP CF219A Drum Unit",
],
"Canon Toner Cartridge": [
"Canon 328 Black Toner (CRG-328)",
"Canon 337 Black Toner (CRG-337)",
"Canon 052 Black Toner",
],
"Paper & Stationery": [
"A4 Paper Ream (500 sheets, 75 GSM)",
"A4 Paper Box (5 reams)",
"Ballpoint Pen Blue (Box of 10)",
"Ballpoint Pen Black (Box of 10)",
"Sticky Notes 76x76mm (Pack of 5)",
"Stapler Pins Box of 1000",
],
"Cables & Connectors": [
"USB-A to USB-B Cable 1.5m (Printer Cable)",
"USB-A to USB-C Cable 1m",
"HDMI Cable 1.5m",
"LAN Cable Cat6 3m",
"VGA Cable 1.8m",
"Power Extension Board 4 Socket",
],
"Storage Media": [
"USB Flash Drive 16GB",
"USB Flash Drive 32GB",
"DVD-R Blank Disc (Pack of 10)",
],
"Cleaning Supplies": [
"Screen Cleaning Kit (Spray + Cloth)",
"Compressed Air Can 400ml",
"Microfiber Cleaning Cloth",
"Keyboard Cleaning Brush",
],
"Batteries & Power": [
"AA Batteries (Pack of 4)",
"AAA Batteries (Pack of 4)",
"UPS Battery 12V 7.2Ah",
],
}
fixed = 0
created = 0
for parent_name, children in structure.items():
# Get or create parent (must be top-level)
parent, p_new = ConsumableCategory.objects.get_or_create(
name=parent_name,
defaults={'parent': None}
)
# Make sure parent has no parent itself
if parent.parent is not None:
parent.parent = None
parent.save()
print(f" Fixed parent: {parent_name} (was a sub-category, now top-level)")
fixed += 1
elif p_new:
print(f" + Created parent: {parent_name}")
created += 1
else:
print(f" ✓ Parent OK: {parent_name}")
for child_name in children:
# Check if this child exists anywhere
existing = ConsumableCategory.objects.filter(name=child_name).first()
if existing:
if existing.parent != parent:
existing.parent = parent
existing.save()
print(f" Fixed: {child_name} → now under {parent_name}")
fixed += 1
else:
print(f" ✓ OK: {child_name}")
else:
ConsumableCategory.objects.create(name=child_name, parent=parent)
print(f" + Created: {child_name}")
created += 1
# Clean up any orphaned duplicates (same name, wrong parent)
print("\nChecking for orphaned categories...")
all_cats = ConsumableCategory.objects.all()
for cat in all_cats:
if cat.parent is None:
# Check if this name should actually be a sub-category
for parent_name, children in structure.items():
if cat.name in children:
parent = ConsumableCategory.objects.filter(name=parent_name, parent=None).first()
if parent and cat.pk != parent.pk:
cat.parent = parent
cat.save()
print(f" Fixed orphan: {cat.name} → under {parent_name}")
fixed += 1
print(f"\n{'='*50}")
print(f"✅ Done! Fixed: {fixed}, Created: {created}")
print(f"\nCategory structure:")
for cat in ConsumableCategory.objects.filter(parent=None).order_by('name'):
sub_count = cat.subcategories.count()
print(f" 📁 {cat.name} ({sub_count} sub-categories)")
for sub in cat.subcategories.all().order_by('name'):
print(f" └─ {sub.name}")
print(f"\nOpen: http://localhost:8090/consumables/categories/")