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
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# See the file COPYING for details.
import csv
import sys
from django.core.management.base import BaseCommand
from django.template.defaultfilters import slugify
from archaeological_warehouse import models
class Command(BaseCommand):
help = 'Migrate to new container management (v3.0.6)'
def handle(self, *args, **options):
to_update = models.Container.objects.filter(
division__pk__isnull=False, parent__isnull=True)
container_types = {}
created_nb = 0
for div_type in models.WarehouseDivision.objects.all():
container_type, c = models.ContainerType.objects.get_or_create(
txt_idx=slugify(div_type.label),
defaults={"label": div_type.label,
"stationary": True})
if c:
created_nb += 1
sys.stdout.write("-> {} created\n".format(
div_type.label))
container_types[div_type.pk] = container_type
for wdl in models.WarehouseDivisionLink.objects.all():
wdl.container_type = container_types[wdl.division_id]
wdl.save()
if created_nb:
sys.stdout.write("* {} container types created\n".format(
created_nb))
to_be_done = to_update.count()
created_nb = 0
potential_duplicate = {}
data = [("id", "warehouse", "reference",
"old cached division", "new cached division")]
for idx, container in enumerate(to_update.values("id").all()):
sys.stdout.write("* Updating: {}/{}\r".format(idx + 1, to_be_done))
sys.stdout.flush()
try:
container = models.Container.objects.get(pk=container["id"])
except models.Container.DoesNotExist:
continue # already merged
if container.responsible_id not in potential_duplicate:
potential_duplicate[container.responsible_id] = {}
parent = None
cached_division = container.cached_division
for division in container.division.order_by(
"division__order").all():
ref = division.reference.strip()
if not ref or ref == "-":
continue
new_container, created = models.Container.objects.get_or_create(
reference=division.reference.strip(),
parent=parent,
container_type=container_types[
division.division.division_id],
location=container.responsible,
responsible=container.responsible)
if created:
created_nb += 1
ref = "{} || {}".format(str(new_container.container_type),
slugify(division.reference.strip()))
if ref not in potential_duplicate[container.responsible_id]:
potential_duplicate[container.responsible_id][ref] = []
if division.reference.strip() not in \
potential_duplicate[container.responsible_id][ref]:
potential_duplicate[container.responsible_id][
ref].append(division.reference.strip())
parent = new_container
if parent:
q = models.Container.objects.filter(
location=container.location,
container_type=container.container_type,
parent=parent,
reference=container.reference).exclude(pk=container.pk)
if q.count():
other = q.all()[0]
other.merge(container)
else:
container.parent = parent
container.save()
data.append((container.id, str(container.responsible),
container.reference, cached_division,
container._generate_cached_division()))
sys.stdout.write("\n* Potential duplicate:")
for warehouse_id in potential_duplicate.keys():
warehouse = models.Warehouse.objects.get(pk=warehouse_id)
for ref in potential_duplicate[warehouse_id]:
items = potential_duplicate[warehouse_id][ref]
if len(items) > 1:
sys.stdout.write(
"\n-> {}: {}".format(warehouse, " ; ".join(items)))
print("")
sys.stdout.write("* {} container created\n".format(created_nb))
if not data:
return
with open("new_containers.csv", 'w+') as f:
w = csv.writer(f)
w.writerows(data)
sys.stdout.write("-> check new containers in \"new_containers.csv\"\n")
|