diff options
Diffstat (limited to 'archaeological_warehouse')
| -rw-r--r-- | archaeological_warehouse/models.py | 90 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 70 | 
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 | 
