summaryrefslogtreecommitdiff
path: root/archaeological_warehouse
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-23 14:20:43 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-28 12:15:24 +0100
commit5e2331815b84e7f31f1b7cd02b3594e12811d66a (patch)
treee0e128bf80472f2947a5f69874b62c705f01b893 /archaeological_warehouse
parentd713093cfabbfb8fe68caa4180de999ab70a3f71 (diff)
downloadIshtar-5e2331815b84e7f31f1b7cd02b3594e12811d66a.tar.bz2
Ishtar-5e2331815b84e7f31f1b7cd02b3594e12811d66a.zip
Warehouse: localisations importer
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r--archaeological_warehouse/models.py90
-rw-r--r--archaeological_warehouse/tests.py70
2 files changed, 140 insertions, 20 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index e094436e1..71751fcbe 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -256,6 +256,10 @@ post_save.connect(post_save_cache, sender=WarehouseType)
post_delete.connect(post_save_cache, sender=WarehouseType)
+NO_DIVISION_ERROR = _(
+ "The division number {} has not been set for the warehouse {}.")
+
+
class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
OwnPerms, MainItem, DivisionContainer, ValueGetter):
SLUG = 'warehouse'
@@ -361,6 +365,72 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
def __str__(self):
return self.name
+ def get_container_type_by_place(self, place: int):
+ """
+ Container type by place based on the default organisation of the
+ warehouse
+
+ :param place: place number
+ :return: container type, other location or None, None
+ """
+ q = WarehouseDivisionLink.objects.filter(
+ warehouse=self).order_by('order')
+ previous_container_types = []
+ for idx, division_link in enumerate(q.all()):
+ if idx == place:
+ current_container_type = division_link.container_type
+ break
+ previous_container_types.append(division_link.container_type_id)
+ else:
+ return None, None
+ return current_container_type, previous_container_types
+
+ @post_importer_action
+ def add_localisations(self, __, value):
+ self._add_localisations(value)
+ add_localisations.post_save = True
+
+ def _add_localisations(self, value, return_errors=False):
+ """
+ Add localisations for this warehouse.
+ Get the default localisation types and set each reference from the
+ value separated by ";"
+
+ :param value: references of localisations separated by ;
+ :param return_errors: return error message default is False
+ :return: return an error message if return_errors set to True
+ """
+ value = value.strip()
+ if not value:
+ if return_errors:
+ return None, _("No value")
+ return
+
+ TMP_SEMI_COLON = "|#|#|"
+ value = value.replace("\\;", TMP_SEMI_COLON) # manage ";" used by a ref
+
+ values = value.split(";")
+
+ divisions = list(WarehouseDivisionLink.objects.filter(
+ warehouse=self).order_by('order'))
+ if len(values) > len(divisions):
+ if return_errors:
+ return str(_("{} values for only {} default divisions set for "
+ "warehouse {}")).format(
+ len(values), len(divisions), self.name)
+ return
+
+ parent = None
+ for idx, value in enumerate(values):
+ value = value.replace(TMP_SEMI_COLON, ";").strip()
+ if not value or value == "-":
+ continue
+ parent, __ = Container.objects.get_or_create(
+ location=self,
+ reference=value,
+ container_type_id=divisions[idx].container_type_id,
+ parent=parent)
+
@property
def short_label(self):
return self.name
@@ -1203,23 +1273,11 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
if return_errors:
return None, _("No value")
return
- q = WarehouseDivisionLink.objects.filter(
- warehouse=self.location).order_by('order')
- current_container_type = None
- error_msg = str(
- _("The division number {} has not been set for the warehouse {}.")
- ).format(place + 1, self.location)
- previous_container_types = []
- for idx, division_link in enumerate(q.all()):
- if idx == place:
- current_container_type = division_link.container_type
- break
- previous_container_types.append(division_link.container_type_id)
- else:
- if return_errors:
- return None, error_msg
- return
+ error_msg = str(NO_DIVISION_ERROR).format(place + 1, self.location)
+
+ current_container_type, previous_container_types = \
+ self.location.get_container_type_by_place(place)
if not current_container_type:
# no division link set at this place
if return_errors:
diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py
index 21833a08f..265a4a7ef 100644
--- a/archaeological_warehouse/tests.py
+++ b/archaeological_warehouse/tests.py
@@ -481,18 +481,80 @@ class ContainerWizardCreationTest(WizardTest, FindInit, TestCase):
class WarehouseTest(TestCase):
fixtures = WAREHOUSE_FIXTURES
- def test_orga_from_warehouse(self):
- w = models.Warehouse.objects.create(
+ def setUp(self):
+ self.warehouse = models.Warehouse.objects.create(
name="Hophop", warehouse_type=models.WarehouseType.objects.all()[0],
address="Adresse"
)
- w.create_attached_organization()
- w = models.Warehouse.objects.get(pk=w.pk)
+ self.container_types = models.ContainerType.objects.all()[:4]
+
+ def test_orga_from_warehouse(self):
+ self.warehouse.create_attached_organization()
+ w = models.Warehouse.objects.get(pk=self.warehouse.pk)
self.assertIsNotNone(w.organization)
self.assertEqual(w.organization.name, "Hophop")
self.assertEqual(w.organization.address, "Adresse")
self.assertEqual(w.address, "")
+ def test_localisation_import(self):
+ container_nb = models.Container.objects.count()
+ base_value = "A;42;allée 3\;2"
+ error = self.warehouse._add_localisations(
+ base_value, return_errors=True)
+ self.assertTrue(error) # no division set
+
+ for idx, ct in enumerate(self.container_types):
+ models.WarehouseDivisionLink.objects.create(
+ container_type=ct, order=idx * 10, warehouse=self.warehouse)
+ too_many_value = "A;42;allée 3\;2;5;42;3"
+ error = self.warehouse._add_localisations(
+ too_many_value, return_errors=True)
+ self.assertTrue(error)
+
+ error = self.warehouse._add_localisations(
+ base_value, return_errors=True)
+ self.assertIsNone(error)
+ parent = None
+ for idx, reference in enumerate(("A", "42", "allée 3;2")):
+ q = models.Container.objects.filter(
+ parent=parent,
+ location=self.warehouse,
+ container_type=self.container_types[idx],
+ reference=reference)
+ self.assertEqual(
+ q.count(), 1, "Division {} {} - parent {} not created".format(
+ self.container_types[idx], reference, parent))
+ parent = q.all()[0]
+ new_container_nb = models.Container.objects.count()
+ self.assertEqual(container_nb + 3, new_container_nb)
+
+ value = "A;42;allée 4"
+ error = self.warehouse._add_localisations(value, return_errors=True)
+ self.assertIsNone(error)
+ # only create a new container
+ self.assertEqual(new_container_nb + 1, models.Container.objects.count())
+ q = models.Container.objects.filter(
+ parent__reference="42",
+ parent__container_type=self.container_types[1],
+ parent__location=self.warehouse,
+ location=self.warehouse,
+ container_type=self.container_types[2],
+ reference="allée 4")
+ self.assertEqual(q.count(), 1)
+
+ # test with an empty localisation
+ value = "A;42;;35"
+ error = self.warehouse._add_localisations(value, return_errors=True)
+ self.assertIsNone(error)
+ q = models.Container.objects.filter(
+ parent__reference="42",
+ parent__container_type=self.container_types[1],
+ parent__location=self.warehouse,
+ location=self.warehouse,
+ container_type=self.container_types[3],
+ reference="35")
+ self.assertEqual(q.count(), 1)
+
class ContainerTest(FindInit, TestCase):
fixtures = WAREHOUSE_FIXTURES