diff options
| -rw-r--r-- | archaeological_warehouse/admin.py | 48 | ||||
| -rw-r--r-- | archaeological_warehouse/forms.py | 665 | ||||
| -rw-r--r-- | archaeological_warehouse/ishtar_menu.py | 136 | ||||
| -rw-r--r-- | archaeological_warehouse/lookups.py | 26 | ||||
| -rw-r--r-- | archaeological_warehouse/models.py | 1049 | ||||
| -rw-r--r-- | archaeological_warehouse/serializers.py | 134 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 682 | ||||
| -rw-r--r-- | archaeological_warehouse/urls.py | 294 | ||||
| -rw-r--r-- | archaeological_warehouse/views.py | 395 | ||||
| -rw-r--r-- | archaeological_warehouse/wizards.py | 116 | 
10 files changed, 1995 insertions, 1550 deletions
diff --git a/archaeological_warehouse/admin.py b/archaeological_warehouse/admin.py index b29c2a8e3..c186950d3 100644 --- a/archaeological_warehouse/admin.py +++ b/archaeological_warehouse/admin.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -34,17 +34,19 @@ class DivisionInline(admin.TabularInline):  class WarehouseAdmin(HistorizedObjectAdmin): -    list_display = ('name', 'warehouse_type', 'town') -    list_filter = ('warehouse_type',) -    search_fields = ('name', 'town') +    list_display = ("name", "warehouse_type", "town") +    list_filter = ("warehouse_type",) +    search_fields = ("name", "town")      model = models.Warehouse      ajax_form_dict = HistorizedObjectAdmin.AJAX_FORM_DICT.copy() -    ajax_form_dict.update({ -        'town': 'town', -        'precise_town': 'town', -        'person_in_charge': 'person', -        'organization': 'organization' -    }) +    ajax_form_dict.update( +        { +            "town": "town", +            "precise_town": "town", +            "person_in_charge": "person", +            "organization": "organization", +        } +    )      form = make_ajax_form(model, ajax_form_dict)      inlines = [DivisionInline]      exclude = ["documents", "main_image"] @@ -54,8 +56,15 @@ admin_site.register(models.Warehouse, WarehouseAdmin)  class ContainerTypeAdmin(GeneralTypeAdmin): -    LIST_DISPLAY = ('label', 'reference', 'stationary', 'length', 'width', -                    'height', 'volume') +    LIST_DISPLAY = ( +        "label", +        "reference", +        "stationary", +        "length", +        "width", +        "height", +        "volume", +    )      model = models.ContainerType      list_filter = ("available", "stationary") @@ -64,17 +73,16 @@ admin_site.register(models.ContainerType, ContainerTypeAdmin)  class ContainerAdmin(HistorizedObjectAdmin): -    list_display = ('reference', 'location', 'container_type',) +    list_display = ( +        "reference", +        "location", +        "container_type", +    )      list_filter = ("container_type",)      model = models.Container -    readonly_fields = HistorizedObjectAdmin.readonly_fields + [ -        'history_date' -    ] +    readonly_fields = HistorizedObjectAdmin.readonly_fields + ["history_date"]      ajax_form_dict = HistorizedObjectAdmin.AJAX_FORM_DICT.copy() -    ajax_form_dict.update({ -        'location': 'warehouse', -        'responsible': 'warehouse' -    }) +    ajax_form_dict.update({"location": "warehouse", "responsible": "warehouse"})      form = make_ajax_form(model, ajax_form_dict)      exclude = ["documents", "main_image"] diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py index 68adc66c1..9bc6de5b0 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2010-2017 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -26,68 +26,106 @@ from django.conf import settings  from django.forms.formsets import formset_factory  from ishtar_common.utils import ugettext_lazy as _ -from ishtar_common.models import Person, valid_id, Town, \ -    SpatialReferenceSystem, Organization, valid_ids, person_type_pks_lazy +from ishtar_common.models import ( +    Person, +    valid_id, +    Town, +    SpatialReferenceSystem, +    Organization, +    valid_ids, +    person_type_pks_lazy, +)  from archaeological_operations.models import ArchaeologicalSite  from archaeological_context_records.models import ContextRecord -from archaeological_finds.models import TreatmentType, FindBasket, \ -    MaterialType, ObjectType, IntegrityType, RemarkabilityType, \ -    ConservatoryState, AlterationType, AlterationCauseType, \ -    TreatmentEmergencyType +from archaeological_finds.models import ( +    TreatmentType, +    FindBasket, +    MaterialType, +    ObjectType, +    IntegrityType, +    RemarkabilityType, +    ConservatoryState, +    AlterationType, +    AlterationCauseType, +    TreatmentEmergencyType, +)  from . import models  from ishtar_common import widgets  from archaeological_operations.widgets import OAWidget  from bootstrap_datepicker.widgets import DatePicker -from ishtar_common.forms import name_validator, reverse_lazy, \ -    get_form_selection, ManageOldType, FinalForm, FormSet, \ -    CustomForm, FieldType, DocumentItemSelect, FormHeader, TableSelect, \ -    CustomFormSearch, MultiSearchForm, LockForm, QAForm -from ishtar_common.forms_common import get_town_field, MergeForm, ManualMerge,\ -    MergeIntoForm -from archaeological_finds.forms import FindMultipleFormSelection, \ -    SelectFindBasketForm +from ishtar_common.forms import ( +    name_validator, +    reverse_lazy, +    get_form_selection, +    ManageOldType, +    FinalForm, +    FormSet, +    CustomForm, +    FieldType, +    DocumentItemSelect, +    FormHeader, +    TableSelect, +    CustomFormSearch, +    MultiSearchForm, +    LockForm, +    QAForm, +) +from ishtar_common.forms_common import ( +    get_town_field, +    MergeForm, +    ManualMerge, +    MergeIntoForm, +) +from archaeological_finds.forms import FindMultipleFormSelection, SelectFindBasketForm  def get_warehouse_field(label=_("Warehouse"), required=True):      # !FIXME hard_link, reverse_lazy doen't seem to work with formsets -    url = "/" + settings.URL_PATH + 'autocomplete-warehouse' +    url = "/" + settings.URL_PATH + "autocomplete-warehouse"      widget = widgets.JQueryAutoComplete(url, associated_model=models.Warehouse) -    return forms.IntegerField(widget=widget, label=label, required=required, -                              validators=[valid_id(models.Warehouse)]) +    return forms.IntegerField( +        widget=widget, +        label=label, +        required=required, +        validators=[valid_id(models.Warehouse)], +    )  class SelectedDivisionForm(ManageOldType, forms.Form):      form_label = _("Default divisions") -    base_model = 'associated_division' -    associated_models = {'container_type': models.ContainerType, -                         'associated_division': models.WarehouseDivisionLink} +    base_model = "associated_division" +    associated_models = { +        "container_type": models.ContainerType, +        "associated_division": models.WarehouseDivisionLink, +    }      container_type = forms.ChoiceField( -        label=_("Division type"), choices=(), -        validators=[valid_id(models.ContainerType)]) -    order = forms.IntegerField(label=_("Order"), min_value=0, -                               required=False) +        label=_("Division type"), +        choices=(), +        validators=[valid_id(models.ContainerType)], +    ) +    order = forms.IntegerField(label=_("Order"), min_value=0, required=False)      def __init__(self, *args, **kwargs):          super(SelectedDivisionForm, self).__init__(*args, **kwargs) -        self.fields['container_type'].choices = \ -            models.ContainerType.get_types( -                dct={"stationary": True}, -                initial=self.init_data.get('container_type')) +        self.fields["container_type"].choices = models.ContainerType.get_types( +            dct={"stationary": True}, initial=self.init_data.get("container_type") +        )  class DivisionFormSet(FormSet):      def clean(self):          """Checks that no divisions are duplicated.""" -        self.check_duplicate(('container_type',), -                             _("There are identical divisions.")) -        self.check_duplicate(('order',), _("Order fields must be different."), -                             check_null=True) +        self.check_duplicate(("container_type",), _("There are identical divisions.")) +        self.check_duplicate( +            ("order",), _("Order fields must be different."), check_null=True +        )  SelectedDivisionFormset = formset_factory( -    SelectedDivisionForm, can_delete=True, formset=DivisionFormSet) +    SelectedDivisionForm, can_delete=True, formset=DivisionFormSet +)  SelectedDivisionFormset.form_label = _("Divisions")  SelectedDivisionFormset.form_admin_name = _("Warehouse - 020 - Divisions")  SelectedDivisionFormset.form_slug = "warehouse-020-divisions" @@ -99,45 +137,54 @@ class WarehouseSelect(CustomForm, TableSelect):      form_slug = "warehouse-001-search"      search_vector = forms.CharField( -        label=_("Full text search"), widget=widgets.SearchWidget( -            'archaeological-warehouse', 'warehouse' -        )) +        label=_("Full text search"), +        widget=widgets.SearchWidget("archaeological-warehouse", "warehouse"), +    )      name = forms.CharField(label=_("Name"))      warehouse_type = forms.ChoiceField(label=_("Warehouse type"), choices=[])      town = get_town_field(label=_("Town"))      def __init__(self, *args, **kwargs):          super(WarehouseSelect, self).__init__(*args, **kwargs) -        self.fields['warehouse_type'].choices = \ -            models.WarehouseType.get_types() -        self.fields['warehouse_type'].help_text = \ -            models.WarehouseType.get_help() +        self.fields["warehouse_type"].choices = models.WarehouseType.get_types() +        self.fields["warehouse_type"].help_text = models.WarehouseType.get_help()  class WarehouseFormSelection(LockForm, CustomFormSearch):      SEARCH_AND_SELECT = True      form_label = _("Warehouse search") -    associated_models = {'pk': models.Warehouse} -    currents = {'pk': models.Warehouse} +    associated_models = {"pk": models.Warehouse} +    currents = {"pk": models.Warehouse}      pk = forms.IntegerField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-warehouse'), -            WarehouseSelect, models.Warehouse, gallery=True, map=True), -        validators=[valid_id(models.Warehouse)]) +            reverse_lazy("get-warehouse"), +            WarehouseSelect, +            models.Warehouse, +            gallery=True, +            map=True, +        ), +        validators=[valid_id(models.Warehouse)], +    )  class WarehouseFormMultiSelection(LockForm, MultiSearchForm):      form_label = _("Warehouse search") -    associated_models = {'pks': models.Warehouse} +    associated_models = {"pks": models.Warehouse}      pk = forms.CharField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-warehouse'), -            WarehouseSelect, models.Warehouse, gallery=True, map=True, -            multiple_select=True +            reverse_lazy("get-warehouse"), +            WarehouseSelect, +            models.Warehouse, +            gallery=True, +            map=True, +            multiple_select=True,          ), -        validators=[valid_ids(models.Warehouse)]) +        validators=[valid_ids(models.Warehouse)], +    )  class WarehouseForm(CustomForm, ManageOldType, forms.Form): @@ -146,93 +193,98 @@ class WarehouseForm(CustomForm, ManageOldType, forms.Form):      form_admin_name = _("Warehouse - 010 - General")      form_slug = "warehouse-010-general"      associated_models = { -        'warehouse_type': models.WarehouseType, -        'person_in_charge': Person, -        'organization': Organization, -        'precise_town': Town, -        'spatial_reference_system': SpatialReferenceSystem +        "warehouse_type": models.WarehouseType, +        "person_in_charge": Person, +        "organization": Organization, +        "precise_town": Town, +        "spatial_reference_system": SpatialReferenceSystem,      } -    name = forms.CharField(label=_("Name"), max_length=200, -                           validators=[name_validator]) -    warehouse_type = forms.ChoiceField(label=_("Warehouse type"), -                                       choices=[]) +    name = forms.CharField(label=_("Name"), max_length=200, validators=[name_validator]) +    warehouse_type = forms.ChoiceField(label=_("Warehouse type"), choices=[])      organization = forms.IntegerField(          label=_("Organization"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-organization'), -            associated_model=Organization, new=True), +            reverse_lazy("autocomplete-organization"), +            associated_model=Organization, +            new=True, +        ),          validators=[valid_id(Organization)], -        required=False) +        required=False, +    )      person_in_charge = forms.IntegerField(          label=_("Person in charge"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person'), -            associated_model=Person, new=True), +            reverse_lazy("autocomplete-person"), associated_model=Person, new=True +        ),          validators=[valid_id(Person)], -        required=False) +        required=False, +    )      create_organization = forms.BooleanField( -        label=_("Create a new organization from this warehouse"), -        required=False +        label=_("Create a new organization from this warehouse"), required=False      ) -    comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, -                              required=False) -    HEADERS['address'] = FormHeader( -        _("Address"), collapse=True, +    comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, required=False) +    HEADERS["address"] = FormHeader( +        _("Address"), +        collapse=True,          help_message=_(              "Only fill the following fields if no organization is provided or "              "if the address of the warehouse is different from the one of the "              "organization. If a new organization is created from this " -            "warehouse, the following fields are used for the organization.")) -    address = forms.CharField(label=_("Address"), widget=forms.Textarea, -                              required=False) -    address_complement = forms.CharField(label=_("Address complement"), -                                         widget=forms.Textarea, required=False) -    postal_code = forms.CharField(label=_("Postal code"), max_length=10, -                                  required=False) -    town = forms.CharField(label=_("Town (freeform)"), max_length=150, -                           required=False) +            "warehouse, the following fields are used for the organization." +        ), +    ) +    address = forms.CharField(label=_("Address"), widget=forms.Textarea, required=False) +    address_complement = forms.CharField( +        label=_("Address complement"), widget=forms.Textarea, required=False +    ) +    postal_code = forms.CharField(label=_("Postal code"), max_length=10, required=False) +    town = forms.CharField(label=_("Town (freeform)"), max_length=150, required=False)      precise_town = get_town_field(required=False) -    country = forms.CharField(label=_("Country"), max_length=30, -                              required=False) +    country = forms.CharField(label=_("Country"), max_length=30, required=False)      phone = forms.CharField(label=_("Phone"), max_length=18, required=False) -    mobile_phone = forms.CharField(label=_("Mobile phone"), max_length=18, -                                   required=False) -    HEADERS['x'] = FormHeader(_("Coordinates")) +    mobile_phone = forms.CharField( +        label=_("Mobile phone"), max_length=18, required=False +    ) +    HEADERS["x"] = FormHeader(_("Coordinates"))      x = forms.FloatField(label=_("X"), required=False)      y = forms.FloatField(label=_("Y"), required=False)      spatial_reference_system = forms.ChoiceField( -        label=_("Spatial Reference System"), required=False, choices=[]) +        label=_("Spatial Reference System"), required=False, choices=[] +    )      TYPES = [ -        FieldType('warehouse_type', models.WarehouseType), -        FieldType('spatial_reference_system', SpatialReferenceSystem) +        FieldType("warehouse_type", models.WarehouseType), +        FieldType("spatial_reference_system", SpatialReferenceSystem),      ]      def __init__(self, *args, **kwargs): -        if 'limits' in kwargs: -            kwargs.pop('limits') +        if "limits" in kwargs: +            kwargs.pop("limits")          super(WarehouseForm, self).__init__(*args, **kwargs)      def clean(self): -        if self.cleaned_data.get("organization", None) and \ -                self.cleaned_data.get("create_organization", None): +        if self.cleaned_data.get("organization", None) and self.cleaned_data.get( +            "create_organization", None +        ):              raise forms.ValidationError( -                _("A new organization is not created if an organization is " -                  "selected.")) +                _( +                    "A new organization is not created if an organization is " +                    "selected." +                ) +            )          return self.cleaned_data      def save(self, user):          dct = self.cleaned_data -        dct['history_modifier'] = user -        dct['warehouse_type'] = models.WarehouseType.objects.get( -            pk=dct['warehouse_type']) -        if 'person_in_charge' in dct and dct['person_in_charge']: -            dct['person_in_charge'] = Person.objects.get( -                pk=dct['person_in_charge']) -        if 'organization' in dct and dct['organization']: -            dct['organization'] = Organization.objects.get( -                pk=dct['organization']) +        dct["history_modifier"] = user +        dct["warehouse_type"] = models.WarehouseType.objects.get( +            pk=dct["warehouse_type"] +        ) +        if "person_in_charge" in dct and dct["person_in_charge"]: +            dct["person_in_charge"] = Person.objects.get(pk=dct["person_in_charge"]) +        if "organization" in dct and dct["organization"]: +            dct["organization"] = Organization.objects.get(pk=dct["organization"])          if not dct.get("spatial_reference_system", None):              dct.pop("spatial_reference_system")          create_orga = dct.pop("create_organization") @@ -261,54 +313,65 @@ class ContainerForm(CustomForm, ManageOldType, forms.Form):      form_admin_name = _("Container - 010 - General")      form_slug = "container-010-general"      file_upload = True -    associated_models = {'container_type': models.ContainerType, -                         'location': models.Warehouse, -                         'responsibility': models.Warehouse, -                         'parent': models.Container} +    associated_models = { +        "container_type": models.ContainerType, +        "location": models.Warehouse, +        "responsibility": models.Warehouse, +        "parent": models.Container, +    }      reference = forms.CharField(label=_("Ref."), max_length=200) -    old_reference = forms.CharField(label=_("Old reference"), required=False, -                                    max_length=200) +    old_reference = forms.CharField( +        label=_("Old reference"), required=False, max_length=200 +    )      container_type = forms.ChoiceField(label=_("Container type"), choices=[])      location = forms.IntegerField(          label=_("Current location (warehouse)"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-warehouse'), -            associated_model=models.Warehouse, new=True), -        validators=[valid_id(models.Warehouse)]) +            reverse_lazy("autocomplete-warehouse"), +            associated_model=models.Warehouse, +            new=True, +        ), +        validators=[valid_id(models.Warehouse)], +    )      parent = forms.IntegerField(          label=_("Parent container"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-container'), +            reverse_lazy("autocomplete-container"),              associated_model=models.Container, -            dynamic_limit=['location']), +            dynamic_limit=["location"], +        ),          validators=[valid_id(models.Container)], -        required=False +        required=False,      )      responsibility = forms.IntegerField(          label=_("Responsibility"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-warehouse'), -            associated_model=models.Warehouse, new=True), +            reverse_lazy("autocomplete-warehouse"), +            associated_model=models.Warehouse, +            new=True, +        ),          validators=[valid_id(models.Warehouse)], -        help_text=_("Automatically attached to the current warehouse if not " -                    "filled."), -        required=False +        help_text=_( +            "Automatically attached to the current warehouse if not " "filled." +        ), +        required=False,      )      weight = forms.FloatField(          label=_("Measured weight (g)"), -        widget=widgets.GramKilogramWidget, required=False) -    comment = forms.CharField(label=_("Comment"), -                              widget=forms.Textarea, required=False) +        widget=widgets.GramKilogramWidget, +        required=False, +    ) +    comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, required=False)      TYPES = [ -        FieldType('container_type', models.ContainerType), +        FieldType("container_type", models.ContainerType),      ]      class Media: -        js = ('forms/container.js',) +        js = ("forms/container.js",)      def __init__(self, *args, **kwargs): -        if 'limits' in kwargs: -            kwargs.pop('limits') +        if "limits" in kwargs: +            kwargs.pop("limits")          super(ContainerForm, self).__init__(*args, **kwargs)      def clean_parent(self): @@ -316,46 +379,54 @@ class ContainerForm(CustomForm, ManageOldType, forms.Form):              return          warehouse_id = self.cleaned_data.get("location")          q = models.Container.objects.filter( -            pk=self.cleaned_data["parent"], -            location_id=warehouse_id) +            pk=self.cleaned_data["parent"], location_id=warehouse_id +        )          if not q.count():              raise forms.ValidationError( -                _("The parent container is not attached to the same " -                  "warehouse.")) +                _("The parent container is not attached to the same " "warehouse.") +            )          return self.cleaned_data["parent"]      def clean(self):          cleaned_data = self.cleaned_data          warehouse = cleaned_data.get("location")          q = models.Container.objects.filter( -            reference=cleaned_data.get("reference"), location__pk=warehouse, +            reference=cleaned_data.get("reference"), +            location__pk=warehouse,              container_type_id=cleaned_data.get("container_type"), -            parent_id=cleaned_data.get("parent") +            parent_id=cleaned_data.get("parent"),          )          pk = None -        if 'pk' in cleaned_data and cleaned_data['pk']: -            pk = int(cleaned_data['pk']) +        if "pk" in cleaned_data and cleaned_data["pk"]: +            pk = int(cleaned_data["pk"])              q = q.exclude(pk=pk)          if q.count(): -            raise forms.ValidationError(_("This reference already exists for " -                                          "this warehouse.")) -        if pk and cleaned_data.get("parent", None) and pk == int( -                cleaned_data.get("parent")): -            raise forms.ValidationError(_("A container cannot be a parent of " -                                          "himself.")) +            raise forms.ValidationError( +                _("This reference already exists for " "this warehouse.") +            ) +        if ( +            pk +            and cleaned_data.get("parent", None) +            and pk == int(cleaned_data.get("parent")) +        ): +            raise forms.ValidationError( +                _("A container cannot be a parent of " "himself.") +            )          return cleaned_data      def save(self, user):          dct = self.cleaned_data -        dct['history_modifier'] = user -        dct['container_type'] = models.ContainerType.objects.get( -            pk=dct['container_type']) -        dct['location'] = models.Warehouse.objects.get(pk=dct['location']) +        dct["history_modifier"] = user +        dct["container_type"] = models.ContainerType.objects.get( +            pk=dct["container_type"] +        ) +        dct["location"] = models.Warehouse.objects.get(pk=dct["location"])          if dct.get("parent", None): -            dct['parent'] = models.Container.objects.get(pk=dct['parent']) +            dct["parent"] = models.Container.objects.get(pk=dct["parent"])          if dct.get("responsibility", None): -            dct['responsibility'] = models.Warehouse.objects.get( -                pk=dct['responsibility']) +            dct["responsibility"] = models.Warehouse.objects.get( +                pk=dct["responsibility"] +            )          new_item = models.Container(**dct)          new_item.save()          return new_item @@ -368,15 +439,15 @@ class ContainerModifyForm(ContainerForm):      def __init__(self, *args, **kwargs):          super(ContainerModifyForm, self).__init__(*args, **kwargs)          fields = OrderedDict() -        idx = self.fields.pop('index') +        idx = self.fields.pop("index")          reordered = False          for key, value in self.fields.items():              fields[key] = value -            if key == 'container_type': -                fields['index'] = idx +            if key == "container_type": +                fields["index"] = idx                  reordered = True          if not reordered: -            fields['index'] = idx +            fields["index"] = idx          self.fields = fields      def clean(self): @@ -396,16 +467,15 @@ class ContainerModifyForm(ContainerForm):              if not q.count():                  cleaned_data["index"] = 1              else: -                cleaned_data["index"] = int(q.aggregate( -                    Max("index"))["index__max"]) + 1 +                cleaned_data["index"] = int(q.aggregate(Max("index"))["index__max"]) + 1          else: -            q = models.Container.objects.filter( -                index=index, location__pk=warehouse) -            if 'pk' in cleaned_data and cleaned_data['pk']: -                q = q.exclude(pk=int(cleaned_data['pk'])) +            q = models.Container.objects.filter(index=index, location__pk=warehouse) +            if "pk" in cleaned_data and cleaned_data["pk"]: +                q = q.exclude(pk=int(cleaned_data["pk"]))              if q.count(): -                raise forms.ValidationError(_("This ID already exists for " -                                              "this warehouse.")) +                raise forms.ValidationError( +                    _("This ID already exists for " "this warehouse.") +                )          return cleaned_data @@ -415,12 +485,11 @@ class ContainerSelect(DocumentItemSelect):      form_slug = "container-001-search"      search_vector = forms.CharField( -        label=_("Full text search"), widget=widgets.SearchWidget( -            'archaeological-warehouse', 'container' -        )) +        label=_("Full text search"), +        widget=widgets.SearchWidget("archaeological-warehouse", "container"), +    )      location_name = get_warehouse_field(label=_("Warehouse")) -    responsibility_name = get_warehouse_field( -        label=_("Warehouse (responsibility)")) +    responsibility_name = get_warehouse_field(label=_("Warehouse (responsibility)"))      container_type = forms.ChoiceField(label=_("Container type"), choices=[])      reference = forms.CharField(label=_("Ref."))      old_reference = forms.CharField(label=_("Old reference")) @@ -432,75 +501,76 @@ class ContainerSelect(DocumentItemSelect):      archaeological_sites = forms.IntegerField(          label=_("Archaeological site (attached to the operation)"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-archaeologicalsite'), -            associated_model=ArchaeologicalSite), -        validators=[valid_id(ArchaeologicalSite)]) +            reverse_lazy("autocomplete-archaeologicalsite"), +            associated_model=ArchaeologicalSite, +        ), +        validators=[valid_id(ArchaeologicalSite)], +    )      archaeological_sites_name = forms.CharField(          label=_("Archaeological site name (attached to the operation)")      )      archaeological_sites_context_record = forms.IntegerField(          label=_("Archaeological site (attached to the context record)"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-archaeologicalsite'), -            associated_model=ArchaeologicalSite), -        validators=[valid_id(ArchaeologicalSite)]) +            reverse_lazy("autocomplete-archaeologicalsite"), +            associated_model=ArchaeologicalSite, +        ), +        validators=[valid_id(ArchaeologicalSite)], +    )      archaeological_sites_context_record_name = forms.CharField(          label=_("Archaeological site name (attached to the context record)")      ) -    code_patriarche = forms.IntegerField(label=_("Operation - Code PATRIARCHE"), -                                         widget=OAWidget) +    code_patriarche = forms.IntegerField( +        label=_("Operation - Code PATRIARCHE"), widget=OAWidget +    )      operation_town = get_town_field(label=_("Operation - town"))      operation_scientist = forms.IntegerField(          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person-permissive'), -            associated_model=Person), -        label=_("Operation - Scientist")) +            reverse_lazy("autocomplete-person-permissive"), associated_model=Person +        ), +        label=_("Operation - Scientist"), +    )      context_record = forms.IntegerField(          label=_("Context record"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-contextrecord'), -            associated_model=ContextRecord), -        validators=[valid_id(ContextRecord)]) +            reverse_lazy("autocomplete-contextrecord"), associated_model=ContextRecord +        ), +        validators=[valid_id(ContextRecord)], +    )      find_label = forms.CharField(label=_("Find - Label"))      find_denomination = forms.CharField(label=_("Find - Denomination"))      description = forms.CharField(label=_("Find - Description"))      material_types = forms.IntegerField(          label=_("Material type"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-materialtype'), -            associated_model=MaterialType), +            reverse_lazy("autocomplete-materialtype"), associated_model=MaterialType +        ),      )      object_types = forms.IntegerField(          label=_("Object type"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-objecttype'), -            associated_model=ObjectType), -    ) -    integrities = forms.ChoiceField(label=_("Integrity / interest"), -                                    choices=[]) -    remarkabilities = forms.ChoiceField(label=_("Remarkability"), -                                        choices=[]) -    conservatory_state = forms.ChoiceField(label=_("Conservatory state"), -                                           choices=[]) -    alterations = forms.ChoiceField( -        label=_("Alteration"), choices=[]) -    alteration_causes = forms.ChoiceField( -        label=_("Alteration cause"), choices=[]) +            reverse_lazy("autocomplete-objecttype"), associated_model=ObjectType +        ), +    ) +    integrities = forms.ChoiceField(label=_("Integrity / interest"), choices=[]) +    remarkabilities = forms.ChoiceField(label=_("Remarkability"), choices=[]) +    conservatory_state = forms.ChoiceField(label=_("Conservatory state"), choices=[]) +    alterations = forms.ChoiceField(label=_("Alteration"), choices=[]) +    alteration_causes = forms.ChoiceField(label=_("Alteration cause"), choices=[])      preservation_to_considers = forms.ChoiceField( -        choices=[], label=_("Preservation type")) -    treatment_emergency = forms.ChoiceField( -        choices=[], label=_("Treatment emergency") +        choices=[], label=_("Preservation type")      ) +    treatment_emergency = forms.ChoiceField(choices=[], label=_("Treatment emergency"))      TYPES = [ -        FieldType('integrities', IntegrityType), -        FieldType('remarkabilities', RemarkabilityType), -        FieldType('conservatory_state', ConservatoryState), -        FieldType('alterations', AlterationType), -        FieldType('alteration_causes', AlterationCauseType), -        FieldType('preservation_to_considers', TreatmentType), -        FieldType('treatment_emergency', TreatmentEmergencyType), -        FieldType('container_type', models.ContainerType) +        FieldType("integrities", IntegrityType), +        FieldType("remarkabilities", RemarkabilityType), +        FieldType("conservatory_state", ConservatoryState), +        FieldType("alterations", AlterationType), +        FieldType("alteration_causes", AlterationCauseType), +        FieldType("preservation_to_considers", TreatmentType), +        FieldType("treatment_emergency", TreatmentEmergencyType), +        FieldType("container_type", models.ContainerType),      ]      SITE_KEYS = {          "archaeological_sites": "attached-to-operation", @@ -511,27 +581,45 @@ class ContainerSelect(DocumentItemSelect):  ContainerFormSelection = get_form_selection( -    'ContainerFormSelection', _("Container search"), 'container', -    models.Container, ContainerSelect, 'get-container', -    _("You should select a container."), new=True, +    "ContainerFormSelection", +    _("Container search"), +    "container", +    models.Container, +    ContainerSelect, +    "get-container", +    _("You should select a container."), +    new=True,      new_message=_("Add a new container"), -    base_form_select=(LockForm, CustomFormSearch) +    base_form_select=(LockForm, CustomFormSearch),  )  MainContainerFormSelection = get_form_selection( -    'ContainerFormSelection', _("Container search"), 'pk', -    models.Container, ContainerSelect, 'get-container', -    _("You should select a container."), gallery=True, map=True, -    base_form_select=CustomFormSearch +    "ContainerFormSelection", +    _("Container search"), +    "pk", +    models.Container, +    ContainerSelect, +    "get-container", +    _("You should select a container."), +    gallery=True, +    map=True, +    base_form_select=CustomFormSearch,  )  MainContainerFormMultiSelection = get_form_selection( -    'ContainerFormSelection', _("Container search"), 'pks', -    models.Container, ContainerSelect, 'get-container', -    _("You should select a container."), gallery=True, map=True, +    "ContainerFormSelection", +    _("Container search"), +    "pks", +    models.Container, +    ContainerSelect, +    "get-container", +    _("You should select a container."), +    gallery=True, +    map=True,      alt_pk_field="pk", -    multi=True, base_form_select=(LockForm, MultiSearchForm) +    multi=True, +    base_form_select=(LockForm, MultiSearchForm),  ) @@ -540,21 +628,25 @@ class MergeContainerForm(MergeForm):          model = models.Container          fields = [] -    FROM_KEY = 'from_container' -    TO_KEY = 'to_container' +    FROM_KEY = "from_container" +    TO_KEY = "to_container"  class ContainerMergeFormSelection(ManualMerge, forms.Form):      SEARCH_AND_SELECT = True      form_label = _("Container to merge") -    associated_models = {'to_merge': models.Container} -    currents = {'to_merge': models.Container} +    associated_models = {"to_merge": models.Container} +    currents = {"to_merge": models.Container}      to_merge = forms.CharField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-container'), ContainerSelect, +            reverse_lazy("get-container"), +            ContainerSelect,              models.Container, -            multiple_select=True,),) +            multiple_select=True, +        ), +    )  class ContainerMergeIntoForm(MergeIntoForm): @@ -563,19 +655,21 @@ class ContainerMergeIntoForm(MergeIntoForm):  class BasePackagingForm(SelectFindBasketForm):      form_label = _("Packaging") -    associated_models = {'treatment_type': TreatmentType, -                         'person': Person, -                         'location': models.Warehouse, -                         'basket': FindBasket} +    associated_models = { +        "treatment_type": TreatmentType, +        "person": Person, +        "location": models.Warehouse, +        "basket": FindBasket, +    }      person = forms.IntegerField(          label=_("Packager"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person'), -            associated_model=Person, new=True), -        validators=[valid_id(Person)]) +            reverse_lazy("autocomplete-person"), associated_model=Person, new=True +        ), +        validators=[valid_id(Person)], +    )      start_date = forms.DateField( -        label=_("Date"), required=False, widget=DatePicker, -        initial=datetime.date.today +        label=_("Date"), required=False, widget=DatePicker, initial=datetime.date.today      ) @@ -592,52 +686,54 @@ class QAContainerFormMulti(QAForm):      PREFIX = "qa"      form_admin_name = _("Container - Quick action - Modify")      form_slug = "container-quickaction-modify" -    base_models = ['qaparent', 'qacontainer_type', -                   'qalocation', 'qaresponsibility'] +    base_models = ["qaparent", "qacontainer_type", "qalocation", "qaresponsibility"]      associated_models = { -        'qaparent': models.Container, -        'qacontainer_type': models.ContainerType, -        'qalocation': models.Warehouse, -        'qaresponsibility': models.Warehouse, +        "qaparent": models.Container, +        "qacontainer_type": models.ContainerType, +        "qalocation": models.Warehouse, +        "qaresponsibility": models.Warehouse,      }      MULTI = True -    REPLACE_FIELDS = [ -        "qaparent", -        "qacontainer_type", -        "qalocation", -        "qaresponsibility" -    ] +    REPLACE_FIELDS = ["qaparent", "qacontainer_type", "qalocation", "qaresponsibility"]      HEADERS = {          "qalocation": FormHeader(_("Warehouse")),      }      SINGLE_FIELDS = [] -    qacontainer_type = forms.ChoiceField(label=_("Container type"), -                                         required=False, choices=[]) +    qacontainer_type = forms.ChoiceField( +        label=_("Container type"), required=False, choices=[] +    )      qalocation = forms.IntegerField(          label=_("Location"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-warehouse'), -            associated_model=models.Warehouse), -        validators=[valid_id(models.Warehouse)], required=False) +            reverse_lazy("autocomplete-warehouse"), associated_model=models.Warehouse +        ), +        validators=[valid_id(models.Warehouse)], +        required=False, +    )      qaresponsibility = forms.IntegerField(          label=_("Responsibility"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-warehouse'), -            associated_model=models.Warehouse), -        validators=[valid_id(models.Warehouse)], required=False) +            reverse_lazy("autocomplete-warehouse"), associated_model=models.Warehouse +        ), +        validators=[valid_id(models.Warehouse)], +        required=False, +    )      qaparent = forms.IntegerField(          label=_("Parent"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-container'), -            dynamic_limit=['qalocation'], -            associated_model=models.Container), -        validators=[valid_id(models.Container)], required=False) +            reverse_lazy("autocomplete-container"), +            dynamic_limit=["qalocation"], +            associated_model=models.Container, +        ), +        validators=[valid_id(models.Container)], +        required=False, +    )      TYPES = [ -        FieldType('qacontainer_type', models.ContainerType), +        FieldType("qacontainer_type", models.ContainerType),      ]      def __init__(self, *args, **kwargs): @@ -668,43 +764,50 @@ class QAContainerFormMulti(QAForm):      def clean(self):          new_values = {}          if self.cleaned_data.get("qacontainer_type", None): -            new_values["container_type_id"] = self.cleaned_data[ -                "qacontainer_type"] +            new_values["container_type_id"] = self.cleaned_data["qacontainer_type"]          if self.cleaned_data.get("qalocation", None): -            new_values["location_id"] = self.cleaned_data[ -                "qalocation"] +            new_values["location_id"] = self.cleaned_data["qalocation"]          if self.cleaned_data.get("qaparent", None): -            new_values["parent_id"] = self.cleaned_data[ -                "qaparent"] +            new_values["parent_id"] = self.cleaned_data["qaparent"]          new_tuples = []          for item in self.items: -            if new_values.get("parent_id", None) and int( -                    new_values["parent_id"]) == item.pk: +            if ( +                new_values.get("parent_id", None) +                and int(new_values["parent_id"]) == item.pk +            ):                  raise forms.ValidationError( -                    _("A container cannot be a parent of himself.")) +                    _("A container cannot be a parent of himself.") +                )              vals = {                  "container_type_id": item.container_type_id,                  "location_id": item.location_id,                  "parent_id": item.parent_id, -                "reference": item.reference.strip() +                "reference": item.reference.strip(),              }              vals.update(new_values) -            c_tuple = (vals["location_id"], vals["container_type_id"], -                       vals["parent_id"], vals["reference"]) +            c_tuple = ( +                vals["location_id"], +                vals["container_type_id"], +                vals["parent_id"], +                vals["reference"], +            )              q = models.Container.objects.filter(**vals).exclude(id=item.id)              if c_tuple in new_tuples or q.count():                  parent = models.Container.objects.get(pk=vals["parent_id"])                  raise forms.ValidationError(                      str( -                        _("Cannot do this changes because it would generate " -                          "many containers with location: {}, container type: " -                          "{}, parent: {} {} and reference: {}. " -                          "Merge these containers first?")).format( +                        _( +                            "Cannot do this changes because it would generate " +                            "many containers with location: {}, container type: " +                            "{}, parent: {} {} and reference: {}. " +                            "Merge these containers first?" +                        ) +                    ).format(                          models.Warehouse.objects.get(pk=vals["location_id"]), -                        models.ContainerType.objects.get( -                            pk=vals["container_type_id"]), -                        parent.container_type, parent.reference, -                        vals["reference"] +                        models.ContainerType.objects.get(pk=vals["container_type_id"]), +                        parent.container_type, +                        parent.reference, +                        vals["reference"],                      )                  )          return self.cleaned_data diff --git a/archaeological_warehouse/ishtar_menu.py b/archaeological_warehouse/ishtar_menu.py index fe012d214..3064671e6 100644 --- a/archaeological_warehouse/ishtar_menu.py +++ b/archaeological_warehouse/ishtar_menu.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -27,51 +27,95 @@ from . import models  MENU_SECTIONS = [ -    (80, SectionItem('warehouse', _("Warehouse"), -     profile_restriction='warehouse', -     css='menu-warehouse', -     childs=[ -         MenuItem('warehouse_search', _("Search"), -                  model=models.Warehouse, -                  access_controls=['view_warehouse', 'view_own_warehouse']), -         MenuItem('warehouse_creation', _("Creation"), -                  model=models.Warehouse, -                  access_controls=['add_warehouse',]), -         MenuItem('warehouse_modification', _("Modification"), -                  model=models.Warehouse, -                  access_controls=['change_warehouse',]), -         MenuItem('warehouse_deletion', _("Deletion"), -                  model=models.Warehouse, -                  access_controls=['change_warehouse',]), -         SectionItem( -             'containers', _("Containers"), -             childs=[ -                 MenuItem('container_search', _("Search"), -                          model=models.Warehouse, -                          access_controls=['view_container', -                                           'view_own_container']), -                 MenuItem('container_creation', _("Creation"), -                          model=models.Warehouse, -                          access_controls=['add_container', -                                           'add_own_container']), -                 MenuItem('container_modification', _("Modification"), -                          model=models.Warehouse, -                          access_controls=['change_container', -                                           'change_own_container']), -                 MenuItem( -                     'container-merge', _("Automatic merge"), -                     model=models.Container, -                     access_controls=['administrator']), -                 MenuItem( -                     'container-manual-merge', _("Manual merge"), -                     model=models.Container, -                     access_controls=['administrator']), -                 MenuItem('container_deletion', _("Deletion"), -                          model=models.Warehouse, -                          access_controls=['change_container', -                                           'change_own_container']), -                 ]) -        ])) +    ( +        80, +        SectionItem( +            "warehouse", +            _("Warehouse"), +            profile_restriction="warehouse", +            css="menu-warehouse", +            childs=[ +                MenuItem( +                    "warehouse_search", +                    _("Search"), +                    model=models.Warehouse, +                    access_controls=["view_warehouse", "view_own_warehouse"], +                ), +                MenuItem( +                    "warehouse_creation", +                    _("Creation"), +                    model=models.Warehouse, +                    access_controls=[ +                        "add_warehouse", +                    ], +                ), +                MenuItem( +                    "warehouse_modification", +                    _("Modification"), +                    model=models.Warehouse, +                    access_controls=[ +                        "change_warehouse", +                    ], +                ), +                MenuItem( +                    "warehouse_deletion", +                    _("Deletion"), +                    model=models.Warehouse, +                    access_controls=[ +                        "change_warehouse", +                    ], +                ), +                SectionItem( +                    "containers", +                    _("Containers"), +                    childs=[ +                        MenuItem( +                            "container_search", +                            _("Search"), +                            model=models.Warehouse, +                            access_controls=["view_container", "view_own_container"], +                        ), +                        MenuItem( +                            "container_creation", +                            _("Creation"), +                            model=models.Warehouse, +                            access_controls=["add_container", "add_own_container"], +                        ), +                        MenuItem( +                            "container_modification", +                            _("Modification"), +                            model=models.Warehouse, +                            access_controls=[ +                                "change_container", +                                "change_own_container", +                            ], +                        ), +                        MenuItem( +                            "container-merge", +                            _("Automatic merge"), +                            model=models.Container, +                            access_controls=["administrator"], +                        ), +                        MenuItem( +                            "container-manual-merge", +                            _("Manual merge"), +                            model=models.Container, +                            access_controls=["administrator"], +                        ), +                        MenuItem( +                            "container_deletion", +                            _("Deletion"), +                            model=models.Warehouse, +                            access_controls=[ +                                "change_container", +                                "change_own_container", +                            ], +                        ), +                    ], +                ), +            ], +        ), +    )  ]  """      MenuItem('warehouse_inventory', _("Inventory"), diff --git a/archaeological_warehouse/lookups.py b/archaeological_warehouse/lookups.py index ea06db3c5..9b221ea5b 100644 --- a/archaeological_warehouse/lookups.py +++ b/archaeological_warehouse/lookups.py @@ -9,22 +9,21 @@ from django.utils.html import escape  from archaeological_warehouse import models -@register('container') +@register("container")  class ContainerLookup(LookupChannel):      model = models.Container      def get_query(self, q, request):          query = Q() -        for term in q.strip().split(' '): +        for term in q.strip().split(" "):              subquery = ( -                Q(reference__icontains=term) | -                Q(container_type__label__icontains=term) | -                Q(cached_label__icontains=term) | -                Q(responsible__name__icontains=term) +                Q(reference__icontains=term) +                | Q(container_type__label__icontains=term) +                | Q(cached_label__icontains=term) +                | Q(responsible__name__icontains=term)              )              query &= subquery -        return self.model.objects.filter(query).order_by( -            'cached_label')[:20] +        return self.model.objects.filter(query).order_by("cached_label")[:20]      def format_match(self, obj):          return escape(force_text(obj.cached_label)) @@ -33,19 +32,16 @@ class ContainerLookup(LookupChannel):          return "<span class='ajax-label'>%s</span>" % item.cached_label -@register('warehouse') +@register("warehouse")  class WarehouseLookup(LookupChannel):      model = models.Warehouse      def get_query(self, q, request):          query = Q() -        for term in q.strip().split(' '): -            subquery = ( -                Q(warehouse_type__label=term) | -                Q(name__icontains=term) -            ) +        for term in q.strip().split(" "): +            subquery = Q(warehouse_type__label=term) | Q(name__icontains=term)              query &= subquery -        return self.model.objects.filter(query).order_by('name')[:20] +        return self.model.objects.filter(query).order_by("name")[:20]      def format_item_display(self, item):          return "<span class='ajax-label'>%s</span>" % item.name diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index fc0184990..29615b6ef 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012-2017 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -27,24 +27,38 @@ from django.contrib.postgres.indexes import GinIndex  from django.core.exceptions import ObjectDoesNotExist  from django.core.urlresolvers import reverse  from django.db.models import Q, Max, Count -from django.db.models.signals import post_save, post_delete, m2m_changed, \ -    pre_delete +from django.db.models.signals import post_save, post_delete, m2m_changed, pre_delete  from django.template.defaultfilters import slugify  from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy  from django.apps import apps -from ishtar_common.data_importer import post_importer_action, \ -    pre_importer_action +from ishtar_common.data_importer import post_importer_action, pre_importer_action  from ishtar_common.model_managers import ExternalIdManager, UUIDModelManager  from ishtar_common.models import ValueGetter, get_current_profile -from ishtar_common.models_common import GeneralType, \ -    LightHistorizedItem, OwnPerms, Address, post_save_cache, \ -    DashboardFormItem, document_attached_changed, SearchAltName, \ -    DynamicRequest, GeoItem, CompleteIdentifierItem, SearchVectorConfig, \ -    DocumentItem, QuickAction, MainItem, Merge +from ishtar_common.models_common import ( +    GeneralType, +    LightHistorizedItem, +    OwnPerms, +    Address, +    post_save_cache, +    DashboardFormItem, +    document_attached_changed, +    SearchAltName, +    DynamicRequest, +    GeoItem, +    CompleteIdentifierItem, +    SearchVectorConfig, +    DocumentItem, +    QuickAction, +    MainItem, +    Merge, +)  from ishtar_common.model_merging import merge_model_objects -from ishtar_common.utils import cached_label_changed, \ -    cached_label_and_geo_changed, get_generated_id +from ishtar_common.utils import ( +    cached_label_changed, +    cached_label_and_geo_changed, +    get_generated_id, +)  from ishtar_common.data_importer import ImporterError @@ -81,7 +95,7 @@ class DivisionContainer(DashboardFormItem):      def number_divisions(self):          q = {              self.BASE_QUERY_LOCATION + "__id": self.pk, -            "container_type__stationary": True +            "container_type__stationary": True,          }          return Container.objects.filter(**q).count() @@ -89,7 +103,7 @@ class DivisionContainer(DashboardFormItem):      def number_containers(self):          q = {              self.BASE_QUERY_LOCATION + "__id": self.pk, -            "container_type__stationary": False +            "container_type__stationary": False,          }          return Container.objects.filter(**q).count() @@ -111,27 +125,30 @@ class DivisionContainer(DashboardFormItem):      @property      def number_of_containers(self): -        return Container.objects.filter( -            **{self.BASE_QUERY_LOCATION: self}).count() +        return Container.objects.filter(**{self.BASE_QUERY_LOCATION: self}).count()      def _number_of_finds_by_place(self):          Find = apps.get_model("archaeological_finds", "Find")          return self._number_of_items_by_place( -            Find, division_key='inside_container__container__') +            Find, division_key="inside_container__container__" +        )      @property      def number_of_finds_by_place(self, update=False): -        return self._get_or_set_stats('_number_of_finds_by_place', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_number_of_finds_by_place", update, expected_type=list +        )      def _number_of_containers_by_place(self):          return self._number_of_items_by_place( -            ContainerTree, 'container_parent__', 'container__children') +            ContainerTree, "container_parent__", "container__children" +        )      @property      def number_of_containers_by_place(self, update=False): -        return self._get_or_set_stats('_number_of_containers_by_place', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_number_of_containers_by_place", update, expected_type=list +        )      def _get_divisions(self, current_path, remaining_division, depth=0):          if not remaining_division: @@ -144,7 +161,7 @@ class DivisionContainer(DashboardFormItem):          base_q = Container.objects.filter(**{query_location: self})          q = base_q -        if self.BASE_QUERY_LOCATION == 'location': +        if self.BASE_QUERY_LOCATION == "location":              exclude = "parent_"              for idx in range(depth):                  exclude += "_parent_" @@ -161,31 +178,28 @@ class DivisionContainer(DashboardFormItem):          if not q.count():              return [current_path]          q = q.values( -            'id', 'reference', 'container_type__label', 'container_type_id' -        ).order_by('container_type__label', 'reference') +            "id", "reference", "container_type__label", "container_type_id" +        ).order_by("container_type__label", "reference")          for ref in q.all(): -            if ref['reference'] == old_ref and \ -                    ref["container_type__label"] == ct: +            if ref["reference"] == old_ref and ref["container_type__label"] == ct:                  continue -            old_ref = ref['reference'] +            old_ref = ref["reference"]              ct = ref["container_type__label"]              cpath = current_path[:]              lbl = self.DIVISION_TEMPLATE.format( -                id=ref["id"], container=ref["container_type__label"], -                ref=ref['reference']) +                id=ref["id"], +                container=ref["container_type__label"], +                ref=ref["reference"], +            )              cpath.append((ref["id"], lbl))              query = { -                "containers__parent__reference": ref['reference'], -                "containers__parent__container_type_id": ref[ -                        "container_type_id"], -                "containers__" + self.BASE_QUERY_LOCATION: self +                "containers__parent__reference": ref["reference"], +                "containers__parent__container_type_id": ref["container_type_id"], +                "containers__" + self.BASE_QUERY_LOCATION: self,              } -            remaining_division = list( -                ContainerType.objects.filter( -                    **query).distinct()) -            for r in self._get_divisions(cpath, remaining_division[:], -                                         depth + 1): +            remaining_division = list(ContainerType.objects.filter(**query).distinct()) +            for r in self._get_divisions(cpath, remaining_division[:], depth + 1):                  res.append(r)          return res @@ -195,13 +209,10 @@ class DivisionContainer(DashboardFormItem):          :return: ordered list of available paths. Each path is a list of          tuple with the container type and the full reference.          """ -        q = { -            "containers__" + self.BASE_QUERY_LOCATION: self -        } -        if self.BASE_QUERY_LOCATION == 'location': +        q = {"containers__" + self.BASE_QUERY_LOCATION: self} +        if self.BASE_QUERY_LOCATION == "location":              q["containers__parent"] = None -        top_divisions = list( -            ContainerType.objects.filter(**q).distinct()) +        top_divisions = list(ContainerType.objects.filter(**q).distinct())          divisions = self._get_divisions([], top_divisions)          return divisions @@ -218,9 +229,7 @@ class DivisionContainer(DashboardFormItem):                  for idx, p in enumerate(reversed(cpath)):                      container_id, __ = p                      div_key = division_key + "parent__" * idx -                    attrs = { -                        div_key + "id": container_id -                    } +                    attrs = {div_key + "id": container_id}                      q = q.filter(**attrs)                  if count_filter:                      q = q.filter(**{count_filter: None}) @@ -236,10 +245,10 @@ class DivisionContainer(DashboardFormItem):                  final_res.append(current_res[:])                  current_res = []                  depth = len(path) -            if path[-1] == '-': +            if path[-1] == "-":                  continue              path = [k[1] for k in path] -            path = path + ['' for __ in range(len_divisions - len(path))] +            path = path + ["" for __ in range(len_divisions - len(path))]              current_res.append((path, nb))          final_res.append(current_res[:])          return final_res @@ -249,25 +258,32 @@ class WarehouseType(GeneralType):      class Meta:          verbose_name = _("Warehouse type")          verbose_name_plural = _("Warehouse types") -        ordering = ('label',) +        ordering = ("label",)  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 {}.") +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' +class Warehouse( +    Address, +    DocumentItem, +    GeoItem, +    CompleteIdentifierItem, +    OwnPerms, +    MainItem, +    DivisionContainer, +    ValueGetter, +): +    SLUG = "warehouse"      APP = "archaeological-warehouse"      MODEL = "warehouse" -    SHOW_URL = 'show-warehouse' -    DELETE_URL = 'delete-warehouse' -    TABLE_COLS = ['name', 'warehouse_type__label'] +    SHOW_URL = "show-warehouse" +    DELETE_URL = "delete-warehouse" +    TABLE_COLS = ["name", "warehouse_type__label"]      NEW_QUERY_ENGINE = True      BASE_SEARCH_VECTORS = [          SearchVectorConfig("name"), @@ -278,7 +294,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,          SearchVectorConfig("comment", "local"),      ]      COL_LABELS = { -        'warehouse_type__label': _("Type"), +        "warehouse_type__label": _("Type"),      }      EXTRA_REQUEST_KEYS = { @@ -288,28 +304,28 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,      }      # alternative names of fields for searches      ALT_NAMES = { -        'name': SearchAltName( -            pgettext_lazy("key for text search", "name"), -            'name__iexact' +        "name": SearchAltName( +            pgettext_lazy("key for text search", "name"), "name__iexact"          ), -        'warehouse_type': SearchAltName( +        "warehouse_type": SearchAltName(              pgettext_lazy("key for text search", "type"), -            'warehouse_type__label__iexact' +            "warehouse_type__label__iexact", +        ), +        "town": SearchAltName( +            pgettext_lazy("key for text search", "town"), +            "precise_town__cached_label__iexact",          ), -        'town': -            SearchAltName( -                pgettext_lazy("key for text search", "town"), -                'precise_town__cached_label__iexact' -            ),      }      GEO_LABEL = "name"      DOWN_MODEL_UPDATE = ["containers"]      CACHED_LABELS = []      QA_LOCK = QuickAction( -        url="warehouse-qa-lock", icon_class="fa fa-lock", -        text=_("Lock/Unlock"), target="many", -        rights=['change_warehouse', 'change_own_warehouse'] +        url="warehouse-qa-lock", +        icon_class="fa fa-lock", +        text=_("Lock/Unlock"), +        target="many", +        rights=["change_warehouse", "change_own_warehouse"],      )      QUICK_ACTIONS = [QA_LOCK] @@ -317,35 +333,53 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,      uuid = models.UUIDField(default=uuid.uuid4)      name = models.CharField(_("Name"), max_length=200) -    warehouse_type = models.ForeignKey(WarehouseType, -                                       verbose_name=_("Warehouse type")) +    warehouse_type = models.ForeignKey(WarehouseType, verbose_name=_("Warehouse type"))      person_in_charge = models.ForeignKey( -        "ishtar_common.Person", on_delete=models.SET_NULL, -        related_name='warehouse_in_charge', -        verbose_name=_("Person in charge"), null=True, blank=True) +        "ishtar_common.Person", +        on_delete=models.SET_NULL, +        related_name="warehouse_in_charge", +        verbose_name=_("Person in charge"), +        null=True, +        blank=True, +    )      organization = models.ForeignKey( -        "ishtar_common.Organization", blank=True, null=True, -        related_name='warehouses', verbose_name=_("Organization"), -        on_delete=models.SET_NULL) +        "ishtar_common.Organization", +        blank=True, +        null=True, +        related_name="warehouses", +        verbose_name=_("Organization"), +        on_delete=models.SET_NULL, +    )      comment = models.TextField(_("Comment"), blank=True, default="")      associated_divisions = models.ManyToManyField( -        'WarehouseDivision', verbose_name=_("Divisions"), blank=True, -        through='WarehouseDivisionLink' +        "WarehouseDivision", +        verbose_name=_("Divisions"), +        blank=True, +        through="WarehouseDivisionLink",      )      documents = models.ManyToManyField( -        "ishtar_common.Document", related_name='warehouses', +        "ishtar_common.Document", +        related_name="warehouses",          verbose_name=_("Documents"), -        blank=True) +        blank=True, +    )      main_image = models.ForeignKey( -        "ishtar_common.Document", related_name='main_image_warehouses', +        "ishtar_common.Document", +        related_name="main_image_warehouses",          on_delete=models.SET_NULL, -        verbose_name=_("Main image"), blank=True, null=True) +        verbose_name=_("Main image"), +        blank=True, +        null=True, +    )      external_id = models.TextField(_("External ID"), blank=True, default="")      auto_external_id = models.BooleanField( -        _("External ID is set automatically"), default=False) +        _("External ID is set automatically"), default=False +    )      max_division_number = models.IntegerField( -        _("Maximum number of divisions"), default=0, -        help_text=_("Automatically generated")) +        _("Maximum number of divisions"), +        default=0, +        help_text=_("Automatically generated"), +    )      SUB_ADDRESSES = ["organization", "person_in_charge"]      class Meta: @@ -359,7 +393,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,              ("delete_own_warehouse", "Can delete own Warehouse"),          )          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      def __str__(self): @@ -373,8 +407,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,          :param place: place number          :return: container type, other location or None, None          """ -        q = WarehouseDivisionLink.objects.filter( -            warehouse=self).order_by('order') +        q = WarehouseDivisionLink.objects.filter(warehouse=self).order_by("order")          previous_container_types = []          for idx, division_link in enumerate(q.all()):              if idx == place: @@ -388,6 +421,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,      @post_importer_action      def add_localisations(self, context, value):          self._add_localisations(context, value) +      add_localisations.post_save = True      def _add_localisations(self, context, value, return_errors=False): @@ -415,17 +449,20 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,          values = value.split(";") -        divisions = list(WarehouseDivisionLink.objects.filter( -            warehouse=self).order_by('order')) +        divisions = list( +            WarehouseDivisionLink.objects.filter(warehouse=self).order_by("order") +        )          parent = None          for idx, value in enumerate(values):              if idx >= len(divisions):                  if return_errors:                      return str( -                        _("{} values for only {} default divisions set for " -                          "warehouse {}")).format( -                        len(values), len(divisions), self.name) +                        _( +                            "{} values for only {} default divisions set for " +                            "warehouse {}" +                        ) +                    ).format(len(values), len(divisions), self.name)                  return              value = value.replace(TMP_SEMI_COLON, ";").strip()              if not value or value == "-": @@ -434,7 +471,8 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,                  location=self,                  reference=value,                  container_type_id=divisions[idx].container_type_id, -                parent=parent) +                parent=parent, +            )              if created and import_object:                  parent.imports.add(import_object) @@ -443,7 +481,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,          return self.name      def natural_key(self): -        return (self.uuid, ) +        return (self.uuid,)      def _get_base_image_path(self):          return "{}/{}".format(self.SLUG, self.external_id) @@ -462,8 +500,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,              orga_type = q.all()[0]          else:              orga_type, __ = OrganizationType.objects.get_or_create( -                txt_idx="undefined", -                defaults={"label": _("Undefined")} +                txt_idx="undefined", defaults={"label": _("Undefined")}              )          dct_orga["organization_type"] = orga_type          dct_orga["name"] = self.name @@ -491,53 +528,52 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,      @property      def default_location_types(self):          return [ -           wd.container_type.label -           for wd in WarehouseDivisionLink.objects.filter( -               warehouse=self).order_by('order').all() if wd.container_type +            wd.container_type.label +            for wd in WarehouseDivisionLink.objects.filter(warehouse=self) +            .order_by("order") +            .all() +            if wd.container_type          ]      @property      def associated_filename(self): -        return datetime.date.today().strftime('%Y-%m-%d') + '-' + \ -            slugify(str(self)) +        return datetime.date.today().strftime("%Y-%m-%d") + "-" + slugify(str(self))      @classmethod      def get_query_owns(cls, ishtaruser): -        return cls._construct_query_own( -            '', cls._get_query_owns_dicts(ishtaruser)) +        return cls._construct_query_own("", cls._get_query_owns_dicts(ishtaruser))      @classmethod      def _get_query_owns_dicts(cls, ishtaruser): -        return [{'person_in_charge__ishtaruser': ishtaruser}] +        return [{"person_in_charge__ishtaruser": ishtaruser}]      def merge(self, item, keep_old=False):          # do not recreate missing divisions          available_divisions = [ -            wd.division -            for wd in WarehouseDivisionLink.objects.filter(warehouse=self) +            wd.division for wd in WarehouseDivisionLink.objects.filter(warehouse=self)          ]          for container in list(item.containers.all()):              container.location = self              container.save() -            for loca in ContainerLocalisation.objects.filter( -                    container=container).all(): +            for loca in ContainerLocalisation.objects.filter(container=container).all():                  if loca.division.division in available_divisions:                      div = WarehouseDivisionLink.objects.get( -                        warehouse=self, -                        division=loca.division.division +                        warehouse=self, division=loca.division.division                      )                      ContainerLocalisation.objects.create( -                        container=container, division=div, -                        reference=loca.reference +                        container=container, division=div, reference=loca.reference                      )                  loca.delete()              container.save()  # force label regeneration          for container in list(item.containers.all()): -            if Container.objects.filter(index=container.index, -                                        location=self).count(): -                container.index = Container.objects.filter( -                    location=self).exclude(id=container.id).all().aggregate( -                    Max("index"))["index__max"] + 1 +            if Container.objects.filter(index=container.index, location=self).count(): +                container.index = ( +                    Container.objects.filter(location=self) +                    .exclude(id=container.id) +                    .all() +                    .aggregate(Max("index"))["index__max"] +                    + 1 +                )              container.location = self              container.save()          for wdiv in WarehouseDivisionLink.objects.filter(warehouse=item).all(): @@ -550,7 +586,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,          self.skip_history_when_saving = True          if not self.external_id or self.auto_external_id: -            external_id = get_generated_id('warehouse_external_id', self) +            external_id = get_generated_id("warehouse_external_id", self)              if external_id != self.external_id:                  self.auto_external_id = True                  self.external_id = external_id @@ -559,8 +595,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,                  return -m2m_changed.connect(document_attached_changed, -                    sender=Warehouse.documents.through) +m2m_changed.connect(document_attached_changed, sender=Warehouse.documents.through)  post_save.connect(cached_label_and_geo_changed, sender=Warehouse) @@ -577,28 +612,35 @@ post_delete.connect(post_save_cache, sender=WarehouseDivision)  class WarehouseDivisionLinkManager(models.Manager):      def get_by_natural_key(self, warehouse, container_type): -        return self.get(warehouse__uuid=warehouse, -                        container_type__txt_idx=container_type) +        return self.get( +            warehouse__uuid=warehouse, container_type__txt_idx=container_type +        )  class ContainerType(GeneralType):      stationary = models.BooleanField( -        _("Stationary"), default=False, -        help_text=_("Container that will not usually be moved. Ex: building, " -                    "room, span, shelf.")) +        _("Stationary"), +        default=False, +        help_text=_( +            "Container that will not usually be moved. Ex: building, " +            "room, span, shelf." +        ), +    )      length = models.IntegerField(_("Length (mm)"), blank=True, null=True)      width = models.IntegerField(_("Width (mm)"), blank=True, null=True)      height = models.IntegerField(_("Height (mm)"), blank=True, null=True)      volume = models.FloatField(_("Volume (l)"), blank=True, null=True)      tare_weight = models.FloatField(_("Tare weight (g)"), blank=True, null=True) -    reference = models.CharField(_("Ref."), max_length=300, blank=True, -                                 null=True) +    reference = models.CharField(_("Ref."), max_length=300, blank=True, null=True)      order = models.IntegerField(_("Order"), default=10)      class Meta:          verbose_name = _("Container type")          verbose_name_plural = _("Container types") -        ordering = ('order', 'label',) +        ordering = ( +            "order", +            "label", +        )  post_save.connect(post_save_cache, sender=ContainerType) @@ -608,18 +650,18 @@ post_delete.connect(post_save_cache, sender=ContainerType)  class WarehouseDivisionLink(models.Model):      RELATED_SET_NAME = "divisions"      RELATED_ATTRS = ["order", "container_type"] -    RELATIVE_MODELS = {Warehouse: 'warehouse'} -    warehouse = models.ForeignKey(Warehouse, related_name='divisions') +    RELATIVE_MODELS = {Warehouse: "warehouse"} +    warehouse = models.ForeignKey(Warehouse, related_name="divisions")      container_type = models.ForeignKey(ContainerType, blank=True, null=True)      division = models.ForeignKey( -        WarehouseDivision, help_text=_("Deprecated - do not use"), -        blank=True, null=True) +        WarehouseDivision, help_text=_("Deprecated - do not use"), blank=True, null=True +    )      order = models.IntegerField(_("Order"), default=10)      objects = WarehouseDivisionLinkManager()      class Meta: -        ordering = ('warehouse', 'order') -        unique_together = ('warehouse', 'division') +        ordering = ("warehouse", "order") +        unique_together = ("warehouse", "division")      def __str__(self):          return "{} - {}".format(self.warehouse, self.container_type) @@ -682,31 +724,47 @@ class ContainerTree(models.Model):      DROP VIEW IF EXISTS containers_tree;      """      container = models.OneToOneField( -        "archaeological_warehouse.Container", verbose_name=_("Container"), -        related_name="container_tree_child", primary_key=True) +        "archaeological_warehouse.Container", +        verbose_name=_("Container"), +        related_name="container_tree_child", +        primary_key=True, +    )      container_parent = models.ForeignKey(          "archaeological_warehouse.Container",          verbose_name=_("Container parent"), -        related_name="container_tree_parent") +        related_name="container_tree_parent", +    )      class Meta:          managed = False -        db_table = 'containers_tree' - - -class Container(DocumentItem, Merge, LightHistorizedItem, -                CompleteIdentifierItem, GeoItem, OwnPerms, MainItem, -                DivisionContainer, ValueGetter): -    SLUG = 'container' +        db_table = "containers_tree" + + +class Container( +    DocumentItem, +    Merge, +    LightHistorizedItem, +    CompleteIdentifierItem, +    GeoItem, +    OwnPerms, +    MainItem, +    DivisionContainer, +    ValueGetter, +): +    SLUG = "container"      APP = "archaeological-warehouse"      MODEL = "container" -    SHOW_URL = 'show-container' -    DELETE_URL = 'delete-container' +    SHOW_URL = "show-container" +    DELETE_URL = "delete-container"      NEW_QUERY_ENGINE = True -    TABLE_COLS = ['container_type__label', 'reference', -                  'location__name', -                  'cached_division', 'old_reference'] -    IMAGE_PREFIX = 'containers/' +    TABLE_COLS = [ +        "container_type__label", +        "reference", +        "location__name", +        "cached_division", +        "old_reference", +    ] +    IMAGE_PREFIX = "containers/"      BASE_SEARCH_VECTORS = [          SearchVectorConfig("reference"),          SearchVectorConfig("container_type__label"), @@ -720,210 +778,208 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      ]      PARENT_SEARCH_VECTORS = ["parent"] -    STATISTIC_MODALITIES_OPTIONS = OrderedDict([ -        ("location__name", _("Location (warehouse)")), -        ("responsibility__name", _("Responsibility (warehouse)")), -        ('finds__base_finds__context_record__operation__cached_label', -         _("Operation")), -    ]) -    STATISTIC_MODALITIES = [ -        key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()] +    STATISTIC_MODALITIES_OPTIONS = OrderedDict( +        [ +            ("location__name", _("Location (warehouse)")), +            ("responsibility__name", _("Responsibility (warehouse)")), +            ( +                "finds__base_finds__context_record__operation__cached_label", +                _("Operation"), +            ), +        ] +    ) +    STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]      GET_VALUES_EXCLUDE_FIELDS = ValueGetter.GET_VALUES_EXCLUDE_FIELDS + [ -        "inside_container", "parent"] +        "inside_container", +        "parent", +    ]      # search parameters      EXTRA_REQUEST_KEYS = { -        'location': 'location__pk', -        'location__name': "location__name", -        'location_id': 'location__pk', -        'responsibility_id': 'responsibility__pk', -        'container_type': 'container_type__pk', -        'reference': 'reference__icontains', -        'old_reference': 'old_reference__icontains', -        'finds__base_finds__context_record__operation': -            'finds__base_finds__context_record__operation', -        'finds__base_finds__context_record': -            'finds__base_finds__context_record', -        'finds': 'finds', -        'container_type__label': 'container_type__label', - +        "location": "location__pk", +        "location__name": "location__name", +        "location_id": "location__pk", +        "responsibility_id": "responsibility__pk", +        "container_type": "container_type__pk", +        "reference": "reference__icontains", +        "old_reference": "old_reference__icontains", +        "finds__base_finds__context_record__operation": "finds__base_finds__context_record__operation", +        "finds__base_finds__context_record": "finds__base_finds__context_record", +        "finds": "finds", +        "container_type__label": "container_type__label",          # dynamic tables -        'container_tree_child__container_parent__id': -        'container_tree_child__container_parent__id' +        "container_tree_child__container_parent__id": "container_tree_child__container_parent__id",      }      COL_LABELS = { -        'cached_location': _("Location - index"), -        'cached_division': _("Precise localisation"), -        'container_type__label': _("Type"), -        "location__name": _("Warehouse") +        "cached_location": _("Location - index"), +        "cached_division": _("Precise localisation"), +        "container_type__label": _("Type"), +        "location__name": _("Warehouse"),      }      GEO_LABEL = "cached_label" -    CACHED_LABELS = ['cached_division', 'cached_label', 'cached_location', -                     'cached_weight'] +    CACHED_LABELS = [ +        "cached_division", +        "cached_label", +        "cached_location", +        "cached_weight", +    ]      # alternative names of fields for searches      ALT_NAMES = { -        'location_name': SearchAltName( -            pgettext_lazy("key for text search", "location"), -            'location__name__iexact' +        "location_name": SearchAltName( +            pgettext_lazy("key for text search", "location"), "location__name__iexact"          ), -        'responsibility_name': SearchAltName( +        "responsibility_name": SearchAltName(              pgettext_lazy("key for text search", "responsibility"), -            'responsibility__name__iexact' +            "responsibility__name__iexact",          ), -        'container_type': SearchAltName( +        "container_type": SearchAltName(              pgettext_lazy("key for text search", "type"), -            'container_type__label__iexact' +            "container_type__label__iexact",          ), -        'reference': SearchAltName( -            pgettext_lazy("key for text search", "reference"), -            'reference__iexact' +        "reference": SearchAltName( +            pgettext_lazy("key for text search", "reference"), "reference__iexact"          ), -        'old_reference': SearchAltName( +        "old_reference": SearchAltName(              pgettext_lazy("key for text search", "old-reference"), -            'old_reference__iexact' +            "old_reference__iexact",          ), -        'comment': SearchAltName( -            pgettext_lazy("key for text search", "comment"), -            'comment__iexact' +        "comment": SearchAltName( +            pgettext_lazy("key for text search", "comment"), "comment__iexact"          ), -        'operation_town': -            SearchAltName( -                pgettext_lazy("key for text search", "operation-town"), -                'finds__base_finds__context_record__operation__' -                'towns__cached_label__iexact' -            ), -        'operation_scientist': -            SearchAltName( -                pgettext_lazy("key for text search", "operation-scientist"), -                'finds__base_finds__context_record__operation__' -                'scientist__cached_label__iexact' -            ), -        'code_patriarche': -            SearchAltName( -                pgettext_lazy("key for text search", "code-patriarche"), -                'finds__base_finds__context_record__operation__' -                'code_patriarche__iexact' -            ), -        'archaeological_sites': -            SearchAltName( -                pgettext_lazy("key for text search", "site"), -                'finds__base_finds__context_record__operation__' -                'archaeological_sites__cached_label__icontains'), -        'archaeological_sites_name': -            SearchAltName( -                pgettext_lazy("key for text search", "site-name"), -                'finds__base_finds__context_record__operation__' -                'archaeological_sites__name__iexact'), -        'archaeological_sites_context_record': -            SearchAltName( -                pgettext_lazy("key for text search", "context-record-site"), -                'finds__base_finds__context_record__archaeological_site__' -                'cached_label__icontains'), -        'archaeological_sites_context_record_name': -            SearchAltName( -                pgettext_lazy("key for text search", -                              "context-record-site-name"), -                'finds__base_finds__context_record__archaeological_site__' -                'name__iexact'), -        'context_record': -            SearchAltName( -                pgettext_lazy("key for text search", "context-record"), -                'finds__base_finds__context_record__cached_label__icontains'), -        'find_label': -            SearchAltName( -                pgettext_lazy("key for text search", "find-label"), -                'finds__label__icontains'), -        'find_denomination': -            SearchAltName( -                pgettext_lazy("key for text search", "find-denomination"), -                'finds__denomination__icontains'), -        'material_types': -            SearchAltName( -                pgettext_lazy("key for text search", "material"), -                'finds__material_types__label__iexact'), -        'object_types': -            SearchAltName( -                pgettext_lazy("key for text search", "object-type"), -                'finds__object_types__label__iexact'), -        'preservation_to_considers': -            SearchAltName( -                pgettext_lazy("key for text search", "preservation"), -                'finds__preservation_to_considers__label__iexact'), -        'conservatory_state': -            SearchAltName( -                pgettext_lazy("key for text search", "conservatory"), -                'finds__conservatory_state__label__iexact'), -        'integrities': -            SearchAltName( -                pgettext_lazy("key for text search", "integrity"), -                'finds__integrities__label__iexact'), -        'remarkabilities': -            SearchAltName( -                pgettext_lazy("key for text search", "remarkability"), -                'finds__remarkabilities__label__iexact'), -        'alterations': -            SearchAltName( -                pgettext_lazy("key for text search", "alterations"), -                'finds__alterations__label__iexact'), -        'alteration_causes': -            SearchAltName( -                pgettext_lazy("key for text search", "alteration-causes"), -                'finds__alteration_causes__label__iexact'), -        'treatment_emergency': -            SearchAltName( -                pgettext_lazy("key for text search", "treatment-emergency"), -                'finds__treatment_emergency__label__iexact'), -        'description': -            SearchAltName( -                pgettext_lazy("key for text search", "find-description"), -                'finds__description__iexact'), -        'empty': SearchAltName( -            pgettext_lazy("key for text search", "empty"), -            'finds' +        "operation_town": SearchAltName( +            pgettext_lazy("key for text search", "operation-town"), +            "finds__base_finds__context_record__operation__" +            "towns__cached_label__iexact", +        ), +        "operation_scientist": SearchAltName( +            pgettext_lazy("key for text search", "operation-scientist"), +            "finds__base_finds__context_record__operation__" +            "scientist__cached_label__iexact", +        ), +        "code_patriarche": SearchAltName( +            pgettext_lazy("key for text search", "code-patriarche"), +            "finds__base_finds__context_record__operation__" "code_patriarche__iexact", +        ), +        "archaeological_sites": SearchAltName( +            pgettext_lazy("key for text search", "site"), +            "finds__base_finds__context_record__operation__" +            "archaeological_sites__cached_label__icontains", +        ), +        "archaeological_sites_name": SearchAltName( +            pgettext_lazy("key for text search", "site-name"), +            "finds__base_finds__context_record__operation__" +            "archaeological_sites__name__iexact", +        ), +        "archaeological_sites_context_record": SearchAltName( +            pgettext_lazy("key for text search", "context-record-site"), +            "finds__base_finds__context_record__archaeological_site__" +            "cached_label__icontains", +        ), +        "archaeological_sites_context_record_name": SearchAltName( +            pgettext_lazy("key for text search", "context-record-site-name"), +            "finds__base_finds__context_record__archaeological_site__" "name__iexact", +        ), +        "context_record": SearchAltName( +            pgettext_lazy("key for text search", "context-record"), +            "finds__base_finds__context_record__cached_label__icontains", +        ), +        "find_label": SearchAltName( +            pgettext_lazy("key for text search", "find-label"), +            "finds__label__icontains", +        ), +        "find_denomination": SearchAltName( +            pgettext_lazy("key for text search", "find-denomination"), +            "finds__denomination__icontains", +        ), +        "material_types": SearchAltName( +            pgettext_lazy("key for text search", "material"), +            "finds__material_types__label__iexact", +        ), +        "object_types": SearchAltName( +            pgettext_lazy("key for text search", "object-type"), +            "finds__object_types__label__iexact", +        ), +        "preservation_to_considers": SearchAltName( +            pgettext_lazy("key for text search", "preservation"), +            "finds__preservation_to_considers__label__iexact", +        ), +        "conservatory_state": SearchAltName( +            pgettext_lazy("key for text search", "conservatory"), +            "finds__conservatory_state__label__iexact", +        ), +        "integrities": SearchAltName( +            pgettext_lazy("key for text search", "integrity"), +            "finds__integrities__label__iexact", +        ), +        "remarkabilities": SearchAltName( +            pgettext_lazy("key for text search", "remarkability"), +            "finds__remarkabilities__label__iexact", +        ), +        "alterations": SearchAltName( +            pgettext_lazy("key for text search", "alterations"), +            "finds__alterations__label__iexact", +        ), +        "alteration_causes": SearchAltName( +            pgettext_lazy("key for text search", "alteration-causes"), +            "finds__alteration_causes__label__iexact",          ), -        'contain_containers': SearchAltName( +        "treatment_emergency": SearchAltName( +            pgettext_lazy("key for text search", "treatment-emergency"), +            "finds__treatment_emergency__label__iexact", +        ), +        "description": SearchAltName( +            pgettext_lazy("key for text search", "find-description"), +            "finds__description__iexact", +        ), +        "empty": SearchAltName(pgettext_lazy("key for text search", "empty"), "finds"), +        "contain_containers": SearchAltName(              pgettext_lazy("key for text search", "contain-containers"), -            'children__isnull' +            "children__isnull",          ), -        'is_stationary': SearchAltName( +        "is_stationary": SearchAltName(              pgettext_lazy("key for text search", "is-stationary"), -            'container_type__stationary' -        ) +            "container_type__stationary", +        ),      }      REVERSED_BOOL_FIELDS = [ -        'children__isnull', -        'documents__image__isnull', -        'documents__associated_file__isnull', -        'documents__associated_url__isnull', +        "children__isnull", +        "documents__image__isnull", +        "documents__associated_file__isnull", +        "documents__associated_url__isnull",      ] -    BOOL_FIELDS = ['container_type__stationary'] -    REVERSED_MANY_COUNTED_FIELDS = ['finds', 'finds_ref'] +    BOOL_FIELDS = ["container_type__stationary"] +    REVERSED_MANY_COUNTED_FIELDS = ["finds", "finds_ref"]      ALT_NAMES.update(LightHistorizedItem.ALT_NAMES)      ALT_NAMES.update(DocumentItem.ALT_NAMES)      DYNAMIC_REQUESTS = { -        'division': DynamicRequest( +        "division": DynamicRequest(              label=_("Division -"), -            app_name='archaeological_warehouse', model_name='WarehouseDivision', -            form_key='division', -            search_key=pgettext_lazy("key for text search", -                                     'division'), -            type_query='division__division__division__txt_idx', -            search_query='division__reference__iexact' +            app_name="archaeological_warehouse", +            model_name="WarehouseDivision", +            form_key="division", +            search_key=pgettext_lazy("key for text search", "division"), +            type_query="division__division__division__txt_idx", +            search_query="division__reference__iexact",          ),      }      QA_EDIT = QuickAction( -        url="container-qa-bulk-update", icon_class="fa fa-pencil", -        text=_("Bulk update"), target="many", -        rights=['change_container', 'change_own_container']) +        url="container-qa-bulk-update", +        icon_class="fa fa-pencil", +        text=_("Bulk update"), +        target="many", +        rights=["change_container", "change_own_container"], +    )      QA_LOCK = QuickAction( -        url="container-qa-lock", icon_class="fa fa-lock", -        text=_("Lock/Unlock"), target="many", -        rights=['change_container', 'change_own_container'] +        url="container-qa-lock", +        icon_class="fa fa-lock", +        text=_("Lock/Unlock"), +        target="many", +        rights=["change_container", "change_own_container"],      )      QUICK_ACTIONS = [QA_EDIT, QA_LOCK] @@ -934,52 +990,76 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      # fields      uuid = models.UUIDField(default=uuid.uuid4)      location = models.ForeignKey( -        Warehouse, verbose_name=_("Location (warehouse)"), -        related_name='containers') +        Warehouse, verbose_name=_("Location (warehouse)"), related_name="containers" +    )      responsible = models.ForeignKey( -        Warehouse, verbose_name=_("Responsible warehouse"), -        related_name='owned_containers', blank=True, null=True, -        help_text=_("Deprecated - do not use") +        Warehouse, +        verbose_name=_("Responsible warehouse"), +        related_name="owned_containers", +        blank=True, +        null=True, +        help_text=_("Deprecated - do not use"),      )      responsibility = models.ForeignKey( -        Warehouse, verbose_name=_("Responsibility"), -        related_name='responsibilities', blank=True, null=True, -        help_text=_("Warehouse that owns the container") +        Warehouse, +        verbose_name=_("Responsibility"), +        related_name="responsibilities", +        blank=True, +        null=True, +        help_text=_("Warehouse that owns the container"), +    ) +    container_type = models.ForeignKey( +        ContainerType, verbose_name=_("Container type"), related_name="containers"      ) -    container_type = models.ForeignKey(ContainerType, -                                       verbose_name=_("Container type"), -                                       related_name="containers")      reference = models.TextField(_("Container ref."))      comment = models.TextField(_("Comment"), blank=True, default="") -    cached_label = models.TextField(_("Localisation"), blank=True, default="", -                                    db_index=True) -    cached_location = models.TextField(_("Cached location"), -                                       blank=True, default="", db_index=True) -    cached_division = models.TextField(_("Cached division"), -                                       blank=True, default="", db_index=True) -    parent = models.ForeignKey("Container", verbose_name=_("Parent container"), -                               on_delete=models.SET_NULL, -                               related_name="children", blank=True, null=True) -    index = models.IntegerField(_("Container ID"), blank=True, null=True, -                                db_index=True) +    cached_label = models.TextField( +        _("Localisation"), blank=True, default="", db_index=True +    ) +    cached_location = models.TextField( +        _("Cached location"), blank=True, default="", db_index=True +    ) +    cached_division = models.TextField( +        _("Cached division"), blank=True, default="", db_index=True +    ) +    parent = models.ForeignKey( +        "Container", +        verbose_name=_("Parent container"), +        on_delete=models.SET_NULL, +        related_name="children", +        blank=True, +        null=True, +    ) +    index = models.IntegerField(_("Container ID"), blank=True, null=True, db_index=True)      weight = models.FloatField(_("Measured weight (g)"), blank=True, null=True)      calculated_weight = models.FloatField( -        _("Calculated weight (g)"), blank=True, null=True) +        _("Calculated weight (g)"), blank=True, null=True +    )      cached_weight = models.FloatField( -        _("Cached weight (g)"), blank=True, null=True, -        help_text=_("Entered weight if available otherwise calculated weight.") +        _("Cached weight (g)"), +        blank=True, +        null=True, +        help_text=_("Entered weight if available otherwise calculated weight."),      )      old_reference = models.TextField(_("Old reference"), blank=True, default="")      external_id = models.TextField(_("External ID"), blank=True, default="")      auto_external_id = models.BooleanField( -        _("External ID is set automatically"), default=False) +        _("External ID is set automatically"), default=False +    )      documents = models.ManyToManyField( -        "ishtar_common.Document", related_name='containers', -        verbose_name=_("Documents"), blank=True) +        "ishtar_common.Document", +        related_name="containers", +        verbose_name=_("Documents"), +        blank=True, +    )      main_image = models.ForeignKey( -        "ishtar_common.Document", related_name='main_image_containers', +        "ishtar_common.Document", +        related_name="main_image_containers",          on_delete=models.SET_NULL, -        verbose_name=_("Main image"), blank=True, null=True) +        verbose_name=_("Main image"), +        blank=True, +        null=True, +    )      DISABLE_POLYGONS = False      MERGE_ATTRIBUTE = "get_merge_key" @@ -988,9 +1068,12 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      class Meta:          verbose_name = _("Container")          verbose_name_plural = _("Containers") -        ordering = ('location', 'index', 'cached_label',) -        unique_together = [('location', 'container_type', 'parent', -                            'reference')] +        ordering = ( +            "location", +            "index", +            "cached_label", +        ) +        unique_together = [("location", "container_type", "parent", "reference")]          permissions = (              ("view_container", "Can view all Containers"),              ("view_own_container", "Can view own Container"), @@ -999,7 +1082,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,              ("delete_own_container", "Can delete own Container"),          )          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      def __str__(self): @@ -1017,8 +1100,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          return depth      def get_max_division_number(self): -        return self.location.get_max_division_number() \ -               - self.start_division_number +        return self.location.get_max_division_number() - self.start_division_number      @property      def number_of_finds_hosted(self): @@ -1049,13 +1131,12 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          return self.parent.external_id      def natural_key(self): -        return (self.uuid, ) +        return (self.uuid,)      @classmethod      @pre_importer_action      def import_get_location(cls, context, value): -        if context.get("container_type", None) and context.get( -                "reference", None): +        if context.get("container_type", None) and context.get("reference", None):              try:                  context["location"] = Warehouse.objects.get(external_id=value)                  return @@ -1085,15 +1166,23 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          :return: True if calculated weight is changed          """          profile = get_current_profile() -        if profile.calculate_weight_on_full and self.finds.filter( -                weight__isnull=True).count(): +        if ( +            profile.calculate_weight_on_full +            and self.finds.filter(weight__isnull=True).count() +        ):              weight = None          else:              weight = sum( -                w for w in self.finds.filter(weight__isnull=False).values_list( -                    "weight", flat=True).all()) -            weight += self.container_type.tare_weight \ -                if self.container_type.tare_weight else 0 +                w +                for w in self.finds.filter(weight__isnull=False) +                .values_list("weight", flat=True) +                .all() +            ) +            weight += ( +                self.container_type.tare_weight +                if self.container_type.tare_weight +                else 0 +            )          if weight != self.calculated_weight:              self.calculated_weight = weight              return True @@ -1103,8 +1192,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      def get_calculated_weight_percent(self):          if not self.calculated_weight or not self.weight:              return 0 -        return (self.calculated_weight -                - self.weight) / self.calculated_weight * 100 +        return (self.calculated_weight - self.weight) / self.calculated_weight * 100      @property      def get_cached_division(self): @@ -1113,8 +1201,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      @property      def get_merge_key(self):          try: -            return str(self.location.uuid) + "|" + \ -                   self._generate_cached_division() +            return str(self.location.uuid) + "|" + self._generate_cached_division()          except Warehouse.DoesNotExist:              return @@ -1123,11 +1210,13 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          try:              doc = Document.objects.get(**{key: value})          except Document.DoesNotExist: -            raise ImporterError(str(_("Document with {}: {} does not " -                                      "exists")).format(key, value)) +            raise ImporterError( +                str(_("Document with {}: {} does not " "exists")).format(key, value) +            )          except Document.MultipleObjectsReturned:              raise ImporterError( -                str(_("Multiple document with {}: {}")).format(key, value)) +                str(_("Multiple document with {}: {}")).format(key, value) +            )          doc.container_id = self.pk          doc.container_ref_id = self.pk          doc.skip_history_when_saving = True @@ -1136,16 +1225,19 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      @post_importer_action      def put_document_by_external_id(self, context, value):          self.put_document_by_key(value, "external_id") +      put_document_by_external_id.post_save = True      @post_importer_action      def put_document_by_reference(self, context, value):          self.put_document_by_key(value, "reference") +      put_document_by_reference.post_save = True      @post_importer_action      def put_document_by_complete_identifier(self, context, value):          self.put_document_by_key(value, "complete_identifier") +      put_document_by_complete_identifier.post_save = True      def _generate_cached_division(self): @@ -1163,8 +1255,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,              for loca in reversed(parents)          ]          try: -            locas.append("{} {}".format(self.container_type.name, -                                        self.reference)) +            locas.append("{} {}".format(self.container_type.name, self.reference))          except ObjectDoesNotExist:  # generate too early on item creation              pass          return " | ".join(locas) @@ -1174,8 +1265,9 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      @classmethod      def _change_child_location(cls, parent): -        for child in cls.objects.filter( -                parent=parent).exclude(location=parent.location).all(): +        for child in ( +            cls.objects.filter(parent=parent).exclude(location=parent.location).all() +        ):              if child.location != parent.location:                  child.location = parent.location                  child.save() @@ -1198,13 +1290,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,                  child.parent = self                  child.save()          self._change_child_location(self) -        super(Container, self).merge(item, keep_old=keep_old, -                                     exclude_fields=exclude_fields) +        super(Container, self).merge( +            item, keep_old=keep_old, exclude_fields=exclude_fields +        )      @classmethod      def get_query_owns(cls, ishtaruser): -        return Q(history_creator=ishtaruser.user_ptr) | \ -            Q(location__person_in_charge__ishtaruser=ishtaruser) +        return Q(history_creator=ishtaruser.user_ptr) | Q( +            location__person_in_charge__ishtaruser=ishtaruser +        )      def get_precise_points(self):          precise_points = super(Container, self).get_precise_points() @@ -1232,7 +1326,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      @property      def associated_filename(self): -        filename = datetime.date.today().strftime('%Y-%m-%d') +        filename = datetime.date.today().strftime("%Y-%m-%d")          filename += "-" + self.reference          filename += "-" + self.location.name          filename += "-" + str(self.index) @@ -1324,8 +1418,10 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          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) +        ( +            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: @@ -1349,7 +1445,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,                  "reference": value,                  "container_type": current_container_type,                  "parent": current_parent, -                "location": self.location +                "location": self.location,              }              q = Container.objects.filter(**dct)              if q.count(): @@ -1358,8 +1454,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,                  if static:                      if return_errors:                          error_msg = str( -                            _("The division {} {} do not exist for the " -                              "location {}.") +                            _("The division {} {} do not exist for the " "location {}.")                          ).format(current_container_type, value, self.location)                          return None, error_msg                      return @@ -1376,103 +1471,128 @@ class Container(DocumentItem, Merge, LightHistorizedItem,      @post_importer_action      def set_localisation_1(self, context, value):          return self.set_localisation(0, value) +      set_localisation_1.post_save = True      @post_importer_action      def set_localisation_2(self, context, value):          return self.set_localisation(1, value) +      set_localisation_2.post_save = True      @post_importer_action      def set_localisation_3(self, context, value):          return self.set_localisation(2, value) +      set_localisation_3.post_save = True      @post_importer_action      def set_localisation_4(self, context, value):          return self.set_localisation(3, value) +      set_localisation_4.post_save = True      @post_importer_action      def set_localisation_5(self, context, value):          return self.set_localisation(4, value) +      set_localisation_5.post_save = True      @post_importer_action      def set_localisation_6(self, context, value):          return self.set_localisation(5, value) +      set_localisation_6.post_save = True      @post_importer_action      def set_localisation_7(self, context, value):          return self.set_localisation(6, value) +      set_localisation_7.post_save = True      @post_importer_action      def set_localisation_8(self, context, value):          return self.set_localisation(7, value) +      set_localisation_8.post_save = True      @post_importer_action      def set_localisation_9(self, context, value):          return self.set_localisation(8, value) +      set_localisation_9.post_save = True      @post_importer_action      def set_static_localisation_1(self, context, value):          return self.set_static_localisation(0, value) +      set_static_localisation_1.post_save = True      @post_importer_action      def set_static_localisation_2(self, context, value):          return self.set_static_localisation(1, value) +      set_static_localisation_2.post_save = True      @post_importer_action      def set_static_localisation_3(self, context, value):          return self.set_static_localisation(2, value) +      set_static_localisation_3.post_save = True      @post_importer_action      def set_static_localisation_4(self, context, value):          return self.set_static_localisation(3, value) +      set_static_localisation_4.post_save = True      @post_importer_action      def set_static_localisation_5(self, context, value):          return self.set_static_localisation(4, value) +      set_static_localisation_5.post_save = True      @post_importer_action      def set_static_localisation_6(self, context, value):          return self.set_static_localisation(5, value) +      set_static_localisation_6.post_save = True      @post_importer_action      def set_static_localisation_7(self, context, value):          return self.set_static_localisation(6, value) +      set_static_localisation_7.post_save = True      @post_importer_action      def set_static_localisation_8(self, context, value):          return self.set_static_localisation(7, value) +      set_static_localisation_8.post_save = True      @post_importer_action      def set_static_localisation_9(self, context, value):          return self.set_static_localisation(8, value) +      set_static_localisation_9.post_save = True      DOC_VALUES = [ -        ("operation_", _("Associated operation - use it with caution, " -                         "only return the first found operation")), -        ("context_record_", -         _("Associated context record - use it with caution, " -           "only return the first found context_record")), -        ("material_types", -         _("Material types inside the container - string")), -        ("material_types_code", -         _("Material types code - string")), +        ( +            "operation_", +            _( +                "Associated operation - use it with caution, " +                "only return the first found operation" +            ), +        ), +        ( +            "context_record_", +            _( +                "Associated context record - use it with caution, " +                "only return the first found context_record" +            ), +        ), +        ("material_types", _("Material types inside the container - string")), +        ("material_types_code", _("Material types code - string")),          ("finds", _("List of associated finds")),      ] @@ -1482,8 +1602,8 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          """          materials = set()          for material in self.finds.exclude( -                material_types__code__isnull=True).values_list( -                "material_types__code", flat=True): +            material_types__code__isnull=True +        ).values_list("material_types__code", flat=True):              materials.add(material)          return "|".join(sorted(materials)) @@ -1493,38 +1613,43 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          """          materials = set()          for material in self.finds.exclude( -                material_types__label__isnull=True).values_list( -                "material_types__label", flat=True): +            material_types__label__isnull=True +        ).values_list("material_types__label", flat=True):              materials.add(material)          return ", ".join(sorted(materials)) -    def get_values(self, prefix='', no_values=False, filtr=None, **kwargs): +    def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):          values = super(Container, self).get_values( -            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) -        from_find = prefix.startswith("container_") or \ -                    prefix.startswith("container_ref_") -        if (not filtr or prefix + 'finds' in filtr) and not from_find and \ -                "finds" not in kwargs.get("exclude", []): +            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs +        ) +        from_find = prefix.startswith("container_") or prefix.startswith( +            "container_ref_" +        ) +        if ( +            (not filtr or prefix + "finds" in filtr) +            and not from_find +            and "finds" not in kwargs.get("exclude", []) +        ):              kwargs["exclude"] = [prefix + "container", prefix + "container_ref"]              # prevent recursive call -            values[prefix + 'finds'] = [ -                f.get_values( -                    prefix=prefix, no_values=True, filtr=None, **kwargs) -                for f in self.finds.distinct().all()] +            values[prefix + "finds"] = [ +                f.get_values(prefix=prefix, no_values=True, filtr=None, **kwargs) +                for f in self.finds.distinct().all() +            ]          if not self.finds.count():              return values          operation_in_filter = filtr and any( -            k for k in filtr if k.startswith(prefix + 'operation')) +            k for k in filtr if k.startswith(prefix + "operation") +        )          cr_in_filter = filtr and any( -            k for k in filtr if k.startswith(prefix + 'context_record')) -        if not filtr or prefix + 'material_types' in filtr: -            values[prefix + 'material_types'] = self.get_material_types() -        if not filtr or prefix + 'material_types_code' in filtr: -            values[prefix + 'material_types_code'] = \ -                self.get_material_types_code() -        if not from_find and ( -                not filtr or operation_in_filter or cr_in_filter): +            k for k in filtr if k.startswith(prefix + "context_record") +        ) +        if not filtr or prefix + "material_types" in filtr: +            values[prefix + "material_types"] = self.get_material_types() +        if not filtr or prefix + "material_types_code" in filtr: +            values[prefix + "material_types_code"] = self.get_material_types_code() +        if not from_find and (not filtr or operation_in_filter or cr_in_filter):              # assume that only one operation is in this container...              # you should know what you are doing when using theses variables              f = self.finds.all()[0] @@ -1534,15 +1659,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,                  if not filtr or cr_in_filter:                      kwargs["exclude"] = [prefix + "operation"]                      for k, v in cr.get_values( -                            prefix=prefix, no_values=True, filtr=None, -                            **kwargs).items(): -                        values[prefix + 'context_record_' + k] = v +                        prefix=prefix, no_values=True, filtr=None, **kwargs +                    ).items(): +                        values[prefix + "context_record_" + k] = v                  if not filtr or operation_in_filter:                      kwargs["exclude"] = [prefix + "context_records"]                      for k, v in cr.operation.get_values( -                            prefix=prefix, no_values=True, filtr=None, -                            **kwargs).items(): -                        values[prefix + 'operation_' + k] = v +                        prefix=prefix, no_values=True, filtr=None, **kwargs +                    ).items(): +                        values[prefix + "operation_" + k] = v          return values      def get_extra_actions(self, request): @@ -1551,11 +1676,17 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          """          # url, base_text, icon, extra_text, extra css class, is a quick action          actions = super(Container, self).get_extra_actions(request) -        can_edit_find = self.can_do(request, 'change_find') +        can_edit_find = self.can_do(request, "change_find")          if can_edit_find:              actions += [ -                (reverse('container-add-treatment', args=[self.pk]), -                 _("Add treatment"), "fa fa-flask", "", "", False), +                ( +                    reverse("container-add-treatment", args=[self.pk]), +                    _("Add treatment"), +                    "fa fa-flask", +                    "", +                    "", +                    False, +                ),              ]          return actions @@ -1579,8 +1710,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,              return          q = Container.objects.filter(location=self.location)          if q.count(): -            self.index = int( -                q.all().aggregate(Max("index"))["index__max"]) + 1 +            self.index = int(q.all().aggregate(Max("index"))["index__max"]) + 1          else:              self.index = 1          if not self.cached_division: @@ -1591,8 +1721,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          parent = self.parent_id          while parent:              number += 1 -            parent = Container.objects.filter(pk=parent).values_list( -                "parent_id")[0][0] +            parent = Container.objects.filter(pk=parent).values_list("parent_id")[0][0]          if number > self.location.max_division_number:              self.location.max_division_number = number              self.location.save() @@ -1608,15 +1737,17 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          if not self.index and not self.container_type.stationary:              self.skip_history_when_saving = True -            q = Container.objects.filter( -                location=self.location -            ).exclude(pk=self.pk).order_by('-index') +            q = ( +                Container.objects.filter(location=self.location) +                .exclude(pk=self.pk) +                .order_by("-index") +            )              self.index = q.all()[0].index + 1 if q.count() else 1              updated = True          self.skip_history_when_saving = True          if not self.external_id or self.auto_external_id: -            external_id = get_generated_id('container_external_id', self) +            external_id = get_generated_id("container_external_id", self)              if external_id != self.external_id:                  updated = True                  self.auto_external_id = True @@ -1629,14 +1760,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,          # remove old location in warehouse          q = ContainerLocalisation.objects.filter(container=self).exclude( -            division__warehouse=self.location) +            division__warehouse=self.location +        )          for loca in q.all():              loca.delete()  def container_post_save(sender, **kwargs):      cached_label_and_geo_changed(sender=sender, **kwargs) -    #TODO: to be deleted??? +    # TODO: to be deleted???      """      if not kwargs.get('instance'):          return @@ -1657,8 +1789,7 @@ def container_post_save(sender, **kwargs):  def container_pre_delete(sender, **kwargs):      instance = kwargs["instance"] -    q = Container.objects.filter( -        container_tree_child__container_parent=instance) +    q = Container.objects.filter(container_tree_child__container_parent=instance)      q.update(cached_division="") @@ -1672,43 +1803,45 @@ def container_post_delete(sender, **kwargs):  post_save.connect(container_post_save, sender=Container)  pre_delete.connect(container_pre_delete, sender=Container)  post_delete.connect(container_post_delete, sender=Container) -m2m_changed.connect(document_attached_changed, -                    sender=Container.documents.through) +m2m_changed.connect(document_attached_changed, sender=Container.documents.through)  class ContainerLocalisationManager(models.Manager): -    #TODO: to be deleted.... +    # TODO: to be deleted....      def get_by_natural_key(self, container, warehouse, container_type): -        return self.get(container__uuid=container, -                        division__warehouse__uuid=warehouse, -                        division__container_type__txt_idx=container_type) +        return self.get( +            container__uuid=container, +            division__warehouse__uuid=warehouse, +            division__container_type__txt_idx=container_type, +        )  class ContainerLocalisation(models.Model): -    #TODO: to be deleted.... -    container = models.ForeignKey(Container, verbose_name=_("Container"), -                                  related_name='division') -    division = models.ForeignKey(WarehouseDivisionLink, -                                 verbose_name=_("Division")) -    reference = models.CharField(_("Reference"), max_length=200, default='') +    # TODO: to be deleted.... +    container = models.ForeignKey( +        Container, verbose_name=_("Container"), related_name="division" +    ) +    division = models.ForeignKey(WarehouseDivisionLink, verbose_name=_("Division")) +    reference = models.CharField(_("Reference"), max_length=200, default="")      objects = ContainerLocalisationManager()      TO_BE_DELETED = True      class Meta:          verbose_name = _("Container localisation")          verbose_name_plural = _("Container localisations") -        ordering = ('container', 'division__order') +        ordering = ("container", "division__order")      def __str__(self): -        return " - ".join((str(self.container), str(self.division), -                           self.reference)) +        return " - ".join((str(self.container), str(self.division), self.reference))      def natural_key(self): -        return self.container.uuid, self.division.warehouse.uuid,\ -               self.division.container_type.txt_idx +        return ( +            self.container.uuid, +            self.division.warehouse.uuid, +            self.division.container_type.txt_idx, +        )      def save(self, *args, **kwargs):          super(ContainerLocalisation, self).save(*args, **kwargs)          self.container.skip_history_when_saving = True -        cached_label_changed(Container, instance=self.container, -                             force_update=True) +        cached_label_changed(Container, instance=self.container, force_update=True) diff --git a/archaeological_warehouse/serializers.py b/archaeological_warehouse/serializers.py index b0cf4d96f..19ae8ba99 100644 --- a/archaeological_warehouse/serializers.py +++ b/archaeological_warehouse/serializers.py @@ -1,13 +1,13 @@  from django.db.models import Q -from ishtar_common.serializers_utils import generic_get_results, \ -    archive_serialization +from ishtar_common.serializers_utils import generic_get_results, archive_serialization  from archaeological_warehouse import models  WAREHOUSE_MODEL_LIST = [ -    models.Warehouse, models.Container, +    models.Warehouse, +    models.Container,      models.WarehouseDivisionLink, -    models.ContainerLocalisation +    models.ContainerLocalisation,  ]  # TODO: associated documents @@ -21,57 +21,76 @@ def generate_warehouse_queryset(base_query_key, ids):          base_key = "{}__{}".format(find_key, base_query_key)          q = Q(**{base_key: ids})          container_ids.update( -            list(models.Container.objects.filter( -                q).values_list("id", flat=True))) -        q_loca = Q( -            **{"container__{}__{}".format(find_key, base_query_key): ids}) +            list(models.Container.objects.filter(q).values_list("id", flat=True)) +        ) +        q_loca = Q(**{"container__{}__{}".format(find_key, base_query_key): ids})          container_loca_ids.update( -            list(models.ContainerLocalisation.objects.filter( -                q_loca).values_list("id", flat=True))) +            list( +                models.ContainerLocalisation.objects.filter(q_loca).values_list( +                    "id", flat=True +                ) +            ) +        )          for container_key in ("containers", "owned_containers"): -            q = Q(** -                  {"{}__{}__{}".format(container_key, find_key, -                                       base_query_key): ids}) -            q_div = Q(** -                      {"warehouse__{}__{}__{}".format( -                          container_key, find_key, base_query_key): ids}) +            q = Q(**{"{}__{}__{}".format(container_key, find_key, base_query_key): ids}) +            q_div = Q( +                **{ +                    "warehouse__{}__{}__{}".format( +                        container_key, find_key, base_query_key +                    ): ids +                } +            )              warehouse_ids.update( -                list(models.Warehouse.objects.filter(q).values_list( -                    "id", flat=True))) +                list(models.Warehouse.objects.filter(q).values_list("id", flat=True)) +            )              warehouse_div_ids.update( -                list(models.WarehouseDivisionLink.objects.filter( -                    q_div).values_list("id", flat=True))) +                list( +                    models.WarehouseDivisionLink.objects.filter(q_div).values_list( +                        "id", flat=True +                    ) +                ) +            )      result_queryset = { -        models.Warehouse.__name__: -            models.Warehouse.objects.filter(id__in=warehouse_ids), -        models.Container.__name__: -            models.Container.objects.filter(id__in=container_ids), -        models.WarehouseDivisionLink.__name__: -            models.WarehouseDivisionLink.objects.filter( -                id__in=warehouse_div_ids), -        models.ContainerLocalisation.__name__: -            models.ContainerLocalisation.objects.filter( -                id__in=container_loca_ids) +        models.Warehouse.__name__: models.Warehouse.objects.filter( +            id__in=warehouse_ids +        ), +        models.Container.__name__: models.Container.objects.filter( +            id__in=container_ids +        ), +        models.WarehouseDivisionLink.__name__: models.WarehouseDivisionLink.objects.filter( +            id__in=warehouse_div_ids +        ), +        models.ContainerLocalisation.__name__: models.ContainerLocalisation.objects.filter( +            id__in=container_loca_ids +        ),      }      return result_queryset -def warehouse_serialization(archive=False, return_empty_types=False, -                            archive_name=None, operation_queryset=None, -                            site_queryset=None, cr_queryset=None, -                            find_queryset=None, warehouse_queryset=None, -                            get_queryset=False, no_geo=True, -                            put_locks=False, lock_user=None): +def warehouse_serialization( +    archive=False, +    return_empty_types=False, +    archive_name=None, +    operation_queryset=None, +    site_queryset=None, +    cr_queryset=None, +    find_queryset=None, +    warehouse_queryset=None, +    get_queryset=False, +    no_geo=True, +    put_locks=False, +    lock_user=None, +):      result_queryset = {}      if operation_queryset:          operation_ids = operation_queryset.values_list("id", flat=True)          base_query_key = "base_finds__context_record__operation_id__in" -        result_queryset = generate_warehouse_queryset(base_query_key, -                                                      operation_ids) +        result_queryset = generate_warehouse_queryset(base_query_key, operation_ids)      elif site_queryset:          site_ids = site_queryset.values_list("id", flat=True) -        base_query_key = "base_finds__context_record__"\ -                         "operation__archaeological_sites__id__in" +        base_query_key = ( +            "base_finds__context_record__" "operation__archaeological_sites__id__in" +        )          result_queryset = generate_warehouse_queryset(base_query_key, site_ids)      elif cr_queryset:          cr_ids = cr_queryset.values_list("id", flat=True) @@ -85,22 +104,24 @@ def warehouse_serialization(archive=False, return_empty_types=False,          warehouse_ids = warehouse_queryset.values_list("id", flat=True)          result_queryset = {              models.Warehouse.__name__: warehouse_queryset, -            models.Container.__name__: -                models.Container.objects.filter( -                    Q(location__id__in=warehouse_ids) | -                    Q(responsible__id__in=warehouse_ids) -                ), -            models.WarehouseDivisionLink.__name__: -                models.WarehouseDivisionLink.objects.filter( -                    warehouse_id__in=warehouse_ids), -            models.ContainerLocalisation.__name__: -                models.ContainerLocalisation.objects.filter( -                    division__warehouse_id__in=warehouse_ids) +            models.Container.__name__: models.Container.objects.filter( +                Q(location__id__in=warehouse_ids) | Q(responsible__id__in=warehouse_ids) +            ), +            models.WarehouseDivisionLink.__name__: models.WarehouseDivisionLink.objects.filter( +                warehouse_id__in=warehouse_ids +            ), +            models.ContainerLocalisation.__name__: models.ContainerLocalisation.objects.filter( +                division__warehouse_id__in=warehouse_ids +            ),          }      if get_queryset:          return result_queryset -    result = generic_get_results(WAREHOUSE_MODEL_LIST, "warehouse", -                                 result_queryset=result_queryset, no_geo=no_geo) +    result = generic_get_results( +        WAREHOUSE_MODEL_LIST, +        "warehouse", +        result_queryset=result_queryset, +        no_geo=no_geo, +    )      if put_locks:          for model in WAREHOUSE_MODEL_LIST:              if not hasattr(model, "locked"): @@ -111,7 +132,10 @@ def warehouse_serialization(archive=False, return_empty_types=False,              q.update(locked=True, lock_user=lock_user)      full_archive = archive_serialization( -        result, archive_dir="warehouse", archive=archive, -        return_empty_types=return_empty_types, archive_name=archive_name, +        result, +        archive_dir="warehouse", +        archive=archive, +        return_empty_types=return_empty_types, +        archive_name=archive_name,      )      return full_archive diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index dc1744312..503057cdf 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2017 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -25,9 +25,15 @@ from django.test.client import Client  from archaeological_finds.tests import FindInit -from ishtar_common.tests import WizardTest, WizardTestFormData as FormData, \ -    TestCase, WAREHOUSE_FIXTURES, GenericSerializationTest, COMMON_FIXTURES, \ -    create_user +from ishtar_common.tests import ( +    WizardTest, +    WizardTestFormData as FormData, +    TestCase, +    WAREHOUSE_FIXTURES, +    GenericSerializationTest, +    COMMON_FIXTURES, +    create_user, +)  from ishtar_common.models import IshtarSiteProfile, SpatialReferenceSystem  from archaeological_operations.models import Operation @@ -47,12 +53,8 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):      def setUp(self):          ope1 = self.create_operation()[0]          ope2 = self.create_operation()[1] -        cr = self.create_context_record( -            data={"label": "CR 1", "operation": ope1} -        )[0] -        cr2 = self.create_context_record( -            data={"label": "CR 2", "operation": ope2} -        )[1] +        cr = self.create_context_record(data={"label": "CR 1", "operation": ope1})[0] +        cr2 = self.create_context_record(data={"label": "CR 2", "operation": ope2})[1]          self.create_finds(data_base={"context_record": cr})          self.create_finds(data_base={"context_record": cr2})          self.create_finds(data_base={"context_record": cr2}) @@ -78,7 +80,7 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              container_type=models.ContainerType.objects.all()[0],              reference="Réf1",              index=1, -            external_id="ref1-1" +            external_id="ref1-1",          )          c2 = models.Container.objects.create(              location=w2, @@ -86,7 +88,7 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              container_type=models.ContainerType.objects.all()[0],              reference="Réf2",              index=2, -            external_id="ref2-2" +            external_id="ref2-2",          )          f0 = self.finds[0]          f0.container = c1 @@ -98,7 +100,7 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              container_type=models.ContainerType.objects.all()[0],              reference="Réf3",              index=1, -            external_id="ref3-1" +            external_id="ref3-1",          )          c4 = models.Container.objects.create(              location=w2, @@ -106,7 +108,7 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              container_type=models.ContainerType.objects.all()[0],              reference="Réf4",              index=2, -            external_id="ref4-2" +            external_id="ref4-2",          )          f1 = self.finds[1]          f1.container = c3 @@ -118,7 +120,7 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              container_type=models.ContainerType.objects.all()[0],              reference="Réf5",              index=1, -            external_id="ref5-2" +            external_id="ref5-2",          )          f2 = self.finds[2]          f2.container = c5 @@ -127,20 +129,16 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):          ct1 = models.ContainerType.objects.all()[0]          ct2 = models.ContainerType.objects.all()[1]          wl1 = models.WarehouseDivisionLink.objects.create( -            warehouse=w1, -            container_type=ct1 +            warehouse=w1, container_type=ct1          )          wl2 = models.WarehouseDivisionLink.objects.create( -            warehouse=w1, -            container_type=ct2 +            warehouse=w1, container_type=ct2          )          wl3 = models.WarehouseDivisionLink.objects.create( -            warehouse=w2, -            container_type=ct2 +            warehouse=w2, container_type=ct2          )          wl4 = models.WarehouseDivisionLink.objects.create( -            warehouse=w3, -            container_type=ct1 +            warehouse=w3, container_type=ct1          )          models.Container.objects.create(              location=c1.location, @@ -149,297 +147,280 @@ class SerializationTest(GenericSerializationTest, FindInit, TestCase):              reference="A1",          )          models.Container.objects.create( -            location=c1.location, -            parent=c1, -            container_type=ct2, -            reference="A2" +            location=c1.location, parent=c1, container_type=ct2, reference="A2"          )          models.Container.objects.create( -            location=c2.location, -            parent=c2, -            container_type=ct2, -            reference="A4" +            location=c2.location, parent=c2, container_type=ct2, reference="A4"          )          models.Container.objects.create( -            location=c3.location, -            parent=c3, -            container_type=ct1, -            reference="A5" +            location=c3.location, parent=c3, container_type=ct1, reference="A5"          )      def test_serialization(self): -        res = self.generic_serialization_test( -            serializers.warehouse_serialization) +        res = self.generic_serialization_test(serializers.warehouse_serialization)          warehouse_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Warehouse")] +            res[("warehouse", "archaeological_warehouse__Warehouse")]          )          self.assertEqual(len(warehouse_json), 3)          container_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Container")] +            res[("warehouse", "archaeological_warehouse__Container")]          )          self.assertEqual(len(container_json), 5 + 4)          div_json = json.loads( -            res[('warehouse', -                 "archaeological_warehouse__WarehouseDivisionLink")] +            res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")]          )          self.assertEqual(len(div_json), 4)          result_queryset = Operation.objects.filter(uuid=self.operations[0].uuid)          res = self.generic_serialization_test( -            serializers.warehouse_serialization, no_test=True, -            kwargs={"operation_queryset": result_queryset} +            serializers.warehouse_serialization, +            no_test=True, +            kwargs={"operation_queryset": result_queryset},          )          warehouse_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Warehouse")] +            res[("warehouse", "archaeological_warehouse__Warehouse")]          )          self.assertEqual(len(warehouse_json), 2)          container_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Container")] +            res[("warehouse", "archaeological_warehouse__Container")]          )          self.assertEqual(len(container_json), 2)          div_json = json.loads( -            res[('warehouse', -                 "archaeological_warehouse__WarehouseDivisionLink")] +            res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")]          )          self.assertEqual(len(div_json), 3)          result_queryset = ContextRecord.objects.filter( -            uuid=self.context_records[0].uuid) +            uuid=self.context_records[0].uuid +        )          res = self.generic_serialization_test( -            serializers.warehouse_serialization, no_test=True, -            kwargs={"cr_queryset": result_queryset} +            serializers.warehouse_serialization, +            no_test=True, +            kwargs={"cr_queryset": result_queryset},          )          warehouse_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Warehouse")] +            res[("warehouse", "archaeological_warehouse__Warehouse")]          )          self.assertEqual(len(warehouse_json), 2)          container_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Container")] +            res[("warehouse", "archaeological_warehouse__Container")]          )          self.assertEqual(len(container_json), 2)          div_json = json.loads( -            res[('warehouse', -                 "archaeological_warehouse__WarehouseDivisionLink")] +            res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")]          )          self.assertEqual(len(div_json), 3)          result_queryset = Find.objects.filter(uuid=self.finds[0].uuid)          res = self.generic_serialization_test( -            serializers.warehouse_serialization, no_test=True, -            kwargs={"find_queryset": result_queryset} +            serializers.warehouse_serialization, +            no_test=True, +            kwargs={"find_queryset": result_queryset},          )          warehouse_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Warehouse")] +            res[("warehouse", "archaeological_warehouse__Warehouse")]          )          self.assertEqual(len(warehouse_json), 2)          container_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Container")] +            res[("warehouse", "archaeological_warehouse__Container")]          )          self.assertEqual(len(container_json), 2)          div_json = json.loads( -            res[('warehouse', -                 "archaeological_warehouse__WarehouseDivisionLink")] +            res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")]          )          self.assertEqual(len(div_json), 3) -        result_queryset = models.Warehouse.objects.filter( -            id=self.warehouses[0].id) +        result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].id)          res = self.generic_serialization_test( -            serializers.warehouse_serialization, no_test=True, -            kwargs={"warehouse_queryset": result_queryset} +            serializers.warehouse_serialization, +            no_test=True, +            kwargs={"warehouse_queryset": result_queryset},          )          warehouse_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Warehouse")] +            res[("warehouse", "archaeological_warehouse__Warehouse")]          )          self.assertEqual(len(warehouse_json), 1)          container_json = json.loads( -            res[('warehouse', "archaeological_warehouse__Container")] +            res[("warehouse", "archaeological_warehouse__Container")]          )          self.assertEqual(len(container_json), 3 + 3)          div_json = json.loads( -            res[('warehouse', -                 "archaeological_warehouse__WarehouseDivisionLink")] +            res[("warehouse", "archaeological_warehouse__WarehouseDivisionLink")]          )          self.assertEqual(len(div_json), 2)      def test_ope_serialization_with_warehouse_filter(self):          res = self.generic_serialization_test( -            operation_serialization, no_test=True, +            operation_serialization, +            no_test=True,          )          ope_json = json.loads( -            res[('operations', 'archaeological_operations__Operation')] +            res[("operations", "archaeological_operations__Operation")]          )          self.assertEqual(len(ope_json), 2) -        result_queryset = models.Warehouse.objects.filter( -            id=self.warehouses[0].pk) +        result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk)          res = self.generic_serialization_test( -            operation_serialization, no_test=True, -            kwargs={"warehouse_queryset": result_queryset} +            operation_serialization, +            no_test=True, +            kwargs={"warehouse_queryset": result_queryset},          )          ope_json = json.loads( -            res[('operations', 'archaeological_operations__Operation')] +            res[("operations", "archaeological_operations__Operation")]          )          self.assertEqual(len(ope_json), 1)      def test_cr_serialization_with_warehouse_filter(self):          res = self.generic_serialization_test( -            cr_serialization, no_test=True, +            cr_serialization, +            no_test=True,          )          cr_json = json.loads( -            res[('context_records', -                 'archaeological_context_records__ContextRecord')] +            res[("context_records", "archaeological_context_records__ContextRecord")]          )          self.assertEqual(len(cr_json), 2) -        result_queryset = models.Warehouse.objects.filter( -            id=self.warehouses[0].pk) +        result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk)          res = self.generic_serialization_test( -            cr_serialization, no_test=True, -            kwargs={"warehouse_queryset": result_queryset} +            cr_serialization, +            no_test=True, +            kwargs={"warehouse_queryset": result_queryset},          )          cr_json = json.loads( -            res[('context_records', -                 'archaeological_context_records__ContextRecord')] +            res[("context_records", "archaeological_context_records__ContextRecord")]          )          self.assertEqual(len(cr_json), 1)      def test_find_serialization_with_warehouse_filter(self):          res = self.generic_serialization_test( -            find_serialization, no_test=True, -        ) -        find_json = json.loads( -            res[('finds', 'archaeological_finds__Find')] +            find_serialization, +            no_test=True,          ) +        find_json = json.loads(res[("finds", "archaeological_finds__Find")])          self.assertEqual(len(find_json), 3) -        bfind_json = json.loads( -            res[('finds', 'archaeological_finds__BaseFind')] -        ) +        bfind_json = json.loads(res[("finds", "archaeological_finds__BaseFind")])          self.assertEqual(len(bfind_json), 3) -        result_queryset = models.Warehouse.objects.filter( -            id=self.warehouses[0].pk) +        result_queryset = models.Warehouse.objects.filter(id=self.warehouses[0].pk)          res = self.generic_serialization_test( -            find_serialization, no_test=True, -            kwargs={"warehouse_queryset": result_queryset} -        ) -        find_json = json.loads( -            res[('finds', 'archaeological_finds__Find')] +            find_serialization, +            no_test=True, +            kwargs={"warehouse_queryset": result_queryset},          ) +        find_json = json.loads(res[("finds", "archaeological_finds__Find")])          self.assertEqual(len(find_json), 1) -        bfind_json = json.loads( -            res[('finds', 'archaeological_finds__BaseFind')] -        ) +        bfind_json = json.loads(res[("finds", "archaeological_finds__BaseFind")])          self.assertEqual(len(bfind_json), 1)      def test_restore(self):          current_number, zip_filename = self.generic_restore_test_genzip( -            serializers.WAREHOUSE_MODEL_LIST, -            serializers.warehouse_serialization) -        self.generic_restore_test(zip_filename, current_number, -                                  serializers.WAREHOUSE_MODEL_LIST) +            serializers.WAREHOUSE_MODEL_LIST, serializers.warehouse_serialization +        ) +        self.generic_restore_test( +            zip_filename, current_number, serializers.WAREHOUSE_MODEL_LIST +        )  class WarehouseWizardCreationTest(WizardTest, FindInit, TestCase):      fixtures = WAREHOUSE_FIXTURES -    url_name = 'warehouse_creation' -    wizard_name = 'warehouse_wizard' +    url_name = "warehouse_creation" +    wizard_name = "warehouse_wizard"      steps = views.warehouse_creation_steps -    redirect_url = "/warehouse_modification/selec-warehouse_modification"\ -                   "?open_item={last_id}" +    redirect_url = ( +        "/warehouse_modification/selec-warehouse_modification" "?open_item={last_id}" +    )      model = models.Warehouse      # back is messing with divisions but it is not a real problem because      # reinit is necessary      test_back = False      form_datas = [          FormData( -            'Warehouse creation', +            "Warehouse creation",              form_datas={ -                'warehouse-warehouse_creation': { -                    'name': 'warehouse-ref', -                    'warehouse_type': None, -                    'location': None, -                    'responsible': None, +                "warehouse-warehouse_creation": { +                    "name": "warehouse-ref", +                    "warehouse_type": None, +                    "location": None, +                    "responsible": None,                  }, -                'divisions-warehouse_creation': [ -                    { -                        'container_type': None, -                        'order': 42 -                    } -                ] +                "divisions-warehouse_creation": [{"container_type": None, "order": 42}],              },          ),          FormData( -            'Warehouse creation with no division', +            "Warehouse creation with no division",              form_datas={ -                'warehouse-warehouse_creation': { -                    'name': 'warehouse-ref', -                    'warehouse_type': None, -                    'location': None, -                    'responsible': None, +                "warehouse-warehouse_creation": { +                    "name": "warehouse-ref", +                    "warehouse_type": None, +                    "location": None, +                    "responsible": None,                  },              }, -            ignored=['divisions-warehouse_creation'] +            ignored=["divisions-warehouse_creation"],          ),      ]      def pre_wizard(self):          main_data = self.form_datas[0].form_datas          alt_data = self.form_datas[1].form_datas -        main_data['warehouse-warehouse_creation']['warehouse_type'] = \ -            models.WarehouseType.objects.all()[0].pk -        alt_data['warehouse-warehouse_creation']['warehouse_type'] = \ -            models.WarehouseType.objects.all()[0].pk -        main_data['divisions-warehouse_creation'][0]['container_type'] = \ -            models.ContainerType.objects.all()[0].pk +        main_data["warehouse-warehouse_creation"][ +            "warehouse_type" +        ] = models.WarehouseType.objects.all()[0].pk +        alt_data["warehouse-warehouse_creation"][ +            "warehouse_type" +        ] = models.WarehouseType.objects.all()[0].pk +        main_data["divisions-warehouse_creation"][0][ +            "container_type" +        ] = models.ContainerType.objects.all()[0].pk          self.warehouse_number = models.Warehouse.objects.count()          self.warehouse_div_link = models.WarehouseDivisionLink.objects.count()          super(WarehouseWizardCreationTest, self).pre_wizard()      def post_wizard(self): -        self.assertEqual(models.Warehouse.objects.count(), -                         self.warehouse_number + 2) -        self.assertEqual(models.WarehouseDivisionLink.objects.count(), -                         self.warehouse_div_link + 1) +        self.assertEqual(models.Warehouse.objects.count(), self.warehouse_number + 2) +        self.assertEqual( +            models.WarehouseDivisionLink.objects.count(), self.warehouse_div_link + 1 +        )  class ContainerWizardCreationTest(WizardTest, FindInit, TestCase):      fixtures = WAREHOUSE_FIXTURES -    url_name = 'container_creation' -    wizard_name = 'container_wizard' +    url_name = "container_creation" +    wizard_name = "container_wizard"      steps = views.container_creation_steps -    redirect_url = '/container_modification/selec-container_modification'\ -                   '?open_item={last_id}' +    redirect_url = ( +        "/container_modification/selec-container_modification" "?open_item={last_id}" +    )      model = models.Container      form_datas = [          FormData( -            'Container creation', +            "Container creation",              form_datas={ -                'container-container_creation': { -                    'reference': 'hop-ref', -                    'container_type': None, -                    'location': None, +                "container-container_creation": { +                    "reference": "hop-ref", +                    "container_type": None, +                    "location": None,                  },              },          ),          FormData( -            'Other container on the same warehouse', +            "Other container on the same warehouse",              form_datas={ -                'container-container_creation': { -                    'reference': 'hop-ref2', -                    'container_type': None, -                    'location': None, +                "container-container_creation": { +                    "reference": "hop-ref2", +                    "container_type": None, +                    "location": None,                  },              },          ),          FormData( -            'Container creation', +            "Container creation",              form_datas={ -                'container-container_creation': { -                    'reference': 'hop-ref3', -                    'container_type': None, -                    'location': None, -                    'parent': None, +                "container-container_creation": { +                    "reference": "hop-ref3", +                    "container_type": None, +                    "location": None, +                    "parent": None,                  },              },          ), @@ -447,35 +428,32 @@ class ContainerWizardCreationTest(WizardTest, FindInit, TestCase):      def pre_wizard(self):          main_warehouse = models.Warehouse.objects.create( -            name="Main", -            warehouse_type=models.WarehouseType.objects.all()[0] +            name="Main", warehouse_type=models.WarehouseType.objects.all()[0]          )          main_data = self.form_datas[0].form_datas          main_data_bis = self.form_datas[1].form_datas          alt_data = self.form_datas[2].form_datas          for data in [main_data, main_data_bis, alt_data]: -            forms_data = data['container-container_creation'] +            forms_data = data["container-container_creation"]              forms_data["responsible"] = main_warehouse.pk              forms_data["location"] = main_warehouse.pk -            forms_data["container_type"] = \ -                models.ContainerType.objects.all()[0].pk +            forms_data["container_type"] = models.ContainerType.objects.all()[0].pk          alt_warehouse = models.Warehouse.objects.create( -            name="Alt", -            warehouse_type=models.WarehouseType.objects.all()[0] -        ) -        alt_data['container-container_creation']["location"] = alt_warehouse.pk -        alt_data['container-container_creation']["parent"] = \ -            models.Container.objects.create( -                reference="Plop", -                container_type=models.ContainerType.objects.all()[1], -                location=alt_warehouse -            ).pk +            name="Alt", warehouse_type=models.WarehouseType.objects.all()[0] +        ) +        alt_data["container-container_creation"]["location"] = alt_warehouse.pk +        alt_data["container-container_creation"][ +            "parent" +        ] = models.Container.objects.create( +            reference="Plop", +            container_type=models.ContainerType.objects.all()[1], +            location=alt_warehouse, +        ).pk          self.container_number = models.Container.objects.count()          super(ContainerWizardCreationTest, self).pre_wizard()      def post_wizard(self): -        self.assertEqual(models.Container.objects.count(), -                         self.container_number + 3) +        self.assertEqual(models.Container.objects.count(), self.container_number + 3)  class WarehouseTest(TestCase): @@ -483,8 +461,9 @@ class WarehouseTest(TestCase):      def setUp(self):          self.warehouse = models.Warehouse.objects.create( -            name="Hophop", warehouse_type=models.WarehouseType.objects.all()[0], -            address="Adresse" +            name="Hophop", +            warehouse_type=models.WarehouseType.objects.all()[0], +            address="Adresse",          )          self.container_types = models.ContainerType.objects.all()[:4] @@ -499,20 +478,20 @@ class WarehouseTest(TestCase):      def test_localisation_import(self):          container_nb = models.Container.objects.count()          base_value = "A;42;allée 3\;2" -        error = self.warehouse._add_localisations( -            None, base_value, return_errors=True) +        error = self.warehouse._add_localisations(None, 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) +                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( -            None, too_many_value, return_errors=True) +            None, too_many_value, return_errors=True +        )          self.assertTrue(error) -        error = self.warehouse._add_localisations( -            None, base_value, return_errors=True) +        error = self.warehouse._add_localisations(None, base_value, return_errors=True)          self.assertIsNone(error)          parent = None          for idx, reference in enumerate(("A", "42", "allée 3;2")): @@ -520,18 +499,21 @@ class WarehouseTest(TestCase):                  parent=parent,                  location=self.warehouse,                  container_type=self.container_types[idx], -                reference=reference) +                reference=reference, +            )              self.assertEqual( -                q.count(), 1, "Division {} {} - parent {} not created".format( -                   self.container_types[idx], reference, parent)) +                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 + len(self.container_types), -                         new_container_nb) +        self.assertEqual(container_nb + len(self.container_types), new_container_nb)          value = "A;42;allée 4" -        error = self.warehouse._add_localisations( -            None, value, return_errors=True) +        error = self.warehouse._add_localisations(None, value, return_errors=True)          self.assertIsNone(error)          # only create a new container          self.assertEqual(new_container_nb + 1, models.Container.objects.count()) @@ -541,13 +523,13 @@ class WarehouseTest(TestCase):              parent__location=self.warehouse,              location=self.warehouse,              container_type=self.container_types[2], -            reference="allée 4") +            reference="allée 4", +        )          self.assertEqual(q.count(), 1)          # test with an empty localisation          value = "A;42;;35" -        error = self.warehouse._add_localisations( -            None, value, return_errors=True) +        error = self.warehouse._add_localisations(None, value, return_errors=True)          self.assertIsNone(error)          q = models.Container.objects.filter(              parent__reference="42", @@ -555,7 +537,8 @@ class WarehouseTest(TestCase):              parent__location=self.warehouse,              location=self.warehouse,              container_type=self.container_types[3], -            reference="35") +            reference="35", +        )          self.assertEqual(q.count(), 1) @@ -564,39 +547,37 @@ class ContainerTest(FindInit, TestCase):      def setUp(self):          self.main_warehouse = models.Warehouse.objects.create( -            name="Main", -            warehouse_type=models.WarehouseType.objects.all()[0] +            name="Main", warehouse_type=models.WarehouseType.objects.all()[0]          ) -        self.division = models.WarehouseDivision.objects.create( -            label='division') -        self.alt_division = models.WarehouseDivision.objects.create( -            label='division2') +        self.division = models.WarehouseDivision.objects.create(label="division") +        self.alt_division = models.WarehouseDivision.objects.create(label="division2")          self.div_link = models.WarehouseDivisionLink.objects.create( -            warehouse=self.main_warehouse, division=self.division) +            warehouse=self.main_warehouse, division=self.division +        )          self.alt_warehouse = models.Warehouse.objects.create( -            name="Alt", -            warehouse_type=models.WarehouseType.objects.all()[0] +            name="Alt", warehouse_type=models.WarehouseType.objects.all()[0]          )      def test_container_search(self):          ct = models.ContainerType.objects.order_by("id").all()[0]          ct2 = models.ContainerType.objects.order_by("id").all()[1]          container_1 = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=ct +            container_type=ct,          )          container_2 = models.Container.objects.create( -            reference="35000", responsible=self.main_warehouse, +            reference="35000", +            responsible=self.main_warehouse,              parent=container_1,              location=self.main_warehouse, -            container_type=ct2 +            container_type=ct2,          )          container_2.index = 42000          container_2.save()          username, password, user = create_user() -        user.user_permissions.add(Permission.objects.get( -            codename='view_warehouse')) +        user.user_permissions.add(Permission.objects.get(codename="view_warehouse"))          client = Client()          client.login(username=username, password=password)          url = "/autocomplete-container/{}/".format(self.main_warehouse.pk) @@ -620,50 +601,57 @@ class ContainerTest(FindInit, TestCase):      def test_form_creation(self):          data = { -            'reference': 'hop-ref', +            "reference": "hop-ref",              "responsible": self.main_warehouse.pk,              "location": self.main_warehouse.pk, -            "container_type": models.ContainerType.objects.all()[0].pk +            "container_type": models.ContainerType.objects.all()[0].pk,          }          form = forms.ContainerForm(data=data)          self.assertTrue(form.is_valid(), msg="{}".format(form.errors))          self.container_number = models.Container.objects.count()          self.create_user()          form.save(self.user) -        self.assertEqual(models.Container.objects.count(), -                         self.container_number + 1) +        self.assertEqual(models.Container.objects.count(), self.container_number + 1)      def test_change_location(self):          container = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=models.ContainerType.objects.all()[0] +            container_type=models.ContainerType.objects.all()[0],          )          container.save()          container = models.Container.objects.get(pk=container.pk)          container_2 = models.Container.objects.create( -            reference="Test2", responsible=self.main_warehouse, +            reference="Test2", +            responsible=self.main_warehouse,              location=self.main_warehouse,              container_type=models.ContainerType.objects.all()[0], -            parent=container +            parent=container,          )          self.assertIn(self.main_warehouse.name, container.cached_location)          models.ContainerLocalisation.objects.create( -            container=container, division=self.div_link, +            container=container, +            division=self.div_link,          ) -        self.assertTrue(models.ContainerLocalisation.objects.filter( -            division__warehouse=self.main_warehouse).count()) +        self.assertTrue( +            models.ContainerLocalisation.objects.filter( +                division__warehouse=self.main_warehouse +            ).count() +        )          # changing location remove irrelevant localisation          other_warehouse = models.Warehouse.objects.create( -            name="Other", -            warehouse_type=models.WarehouseType.objects.all()[0] +            name="Other", warehouse_type=models.WarehouseType.objects.all()[0]          )          container.location = other_warehouse          container.save() -        self.assertFalse(models.ContainerLocalisation.objects.filter( -            division__warehouse=self.main_warehouse).count()) +        self.assertFalse( +            models.ContainerLocalisation.objects.filter( +                division__warehouse=self.main_warehouse +            ).count() +        )          container_2 = models.Container.objects.get(pk=container_2.pk)          self.assertEqual(container_2.location, other_warehouse) @@ -710,24 +698,21 @@ class ContainerTest(FindInit, TestCase):      def test_update_containers_on_warehouse_update(self):          container = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=models.ContainerType.objects.all()[0] +            container_type=models.ContainerType.objects.all()[0],          )          container.save()          container = models.Container.objects.get(pk=container.pk)          self.assertIn(self.main_warehouse.name, container.cached_location)          self.main_warehouse.name = "New name"          self.main_warehouse.save() +        self.assertEqual(models.Container.objects.filter(need_update=True).count(), 1)          self.assertEqual( -            models.Container.objects.filter( -                need_update=True -            ).count(), 1) -        self.assertEqual( -            models.Container.objects.filter( -                pk=container.pk, -                need_update=True -            ).count(), 1) +            models.Container.objects.filter(pk=container.pk, need_update=True).count(), +            1, +        )          container = models.Container.objects.get(pk=container.pk)          # process pending update          container.skip_history_when_saving = True @@ -738,15 +723,17 @@ class ContainerTest(FindInit, TestCase):      def test_update_container_localisation_on_warehouse_update(self):          profile, created = IshtarSiteProfile.objects.get_or_create( -            slug='default', active=True) +            slug="default", active=True +        )          profile.mapping = True          profile.locate_warehouses = True          profile.save()          wgs84 = SpatialReferenceSystem.objects.get(srid=4326)          container = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=models.ContainerType.objects.all()[0] +            container_type=models.ContainerType.objects.all()[0],          )          container.save()          self.assertEqual(container.x, None) @@ -757,10 +744,9 @@ class ContainerTest(FindInit, TestCase):          main_warehouse.save()          # an update is pending          self.assertEqual( -            models.Container.objects.filter( -                pk=container.pk, -                need_update=True -            ).count(), 1) +            models.Container.objects.filter(pk=container.pk, need_update=True).count(), +            1, +        )          # process pending update          container = models.Container.objects.get(pk=container.pk) @@ -775,64 +761,70 @@ class ContainerTest(FindInit, TestCase):      def test_external_id(self):          ct = models.ContainerType.objects.all()[0]          container_1 = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=ct +            container_type=ct,          )          container_2 = models.Container.objects.create( -            reference="Test 2", responsible=self.main_warehouse, +            reference="Test 2", +            responsible=self.main_warehouse,              parent=container_1,              location=self.main_warehouse, -            container_type=ct +            container_type=ct,          )          container_3 = models.Container.objects.create( -            reference="Test 3", responsible=self.main_warehouse, +            reference="Test 3", +            responsible=self.main_warehouse,              parent=container_2,              location=self.main_warehouse, -            container_type=ct +            container_type=ct,          )          self.assertEqual(              container_1.external_id,              "{}-{}-{}".format( -                self.main_warehouse.external_id, ct.txt_idx, -                container_1.reference)) +                self.main_warehouse.external_id, ct.txt_idx, container_1.reference +            ), +        )          self.assertEqual(              container_2.external_id,              "{}-{}-{}".format( -                container_1.external_id, ct.txt_idx, -                container_2.reference)) +                container_1.external_id, ct.txt_idx, container_2.reference +            ), +        )          self.assertEqual(              container_3.external_id,              "{}-{}-{}".format( -                container_2.external_id, ct.txt_idx, -                container_3.reference)) +                container_2.external_id, ct.txt_idx, container_3.reference +            ), +        )      def test_merge_candidate(self):          ct = models.ContainerType.objects.all()[0]          container_1 = models.Container.objects.create( -            reference="Test", responsible=self.main_warehouse, +            reference="Test", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=ct) +            container_type=ct, +        )          init_mc = container_1.merge_candidate.count()          container_2 = models.Container.objects.create( -            reference="TEST", responsible=self.main_warehouse, +            reference="TEST", +            responsible=self.main_warehouse,              location=self.main_warehouse, -            container_type=ct) -        self.assertEqual(container_1.merge_candidate.count(), -                         init_mc + 1) +            container_type=ct, +        ) +        self.assertEqual(container_1.merge_candidate.count(), init_mc + 1)          container_1.archive() -        self.assertEqual(container_1.merge_candidate.count(), -                         init_mc) +        self.assertEqual(container_1.merge_candidate.count(), init_mc)          container_1 = models.Container.objects.get(pk=container_1.pk)          container_1.archived = False          container_1.save()          container_2 = models.Container.objects.get(pk=container_2.pk) -        self.assertEqual(container_1.merge_candidate.count(), -                         init_mc + 1) +        self.assertEqual(container_1.merge_candidate.count(), init_mc + 1)          container_2.location = self.alt_warehouse          container_2.save() -        self.assertEqual(container_1.merge_candidate.count(), -                         init_mc) +        self.assertEqual(container_1.merge_candidate.count(), init_mc)      def test_merge_container(self):          ct = models.ContainerType.objects.all()[0] @@ -845,9 +837,8 @@ class ContainerTest(FindInit, TestCase):          find2 = self.finds[2]          container_1 = models.Container.objects.create( -            reference="Test 1", -            location=self.main_warehouse, -            container_type=ct) +            reference="Test 1", location=self.main_warehouse, container_type=ct +        )          find0.container = container_1          find0.container_ref = container_1          find0.save() @@ -856,20 +847,18 @@ class ContainerTest(FindInit, TestCase):          find1.save()          container_2 = models.Container.objects.create( -            reference="Test 2", -            location=self.alt_warehouse, -            container_type=ct2) +            reference="Test 2", location=self.alt_warehouse, container_type=ct2 +        )          find2.container = container_2          find2.container_ref = container_2          find2.save()          container_1.merge(container_2)          container_1 = models.Container.objects.get(pk=container_1.pk) -        self.assertEqual( -            models.Container.objects.filter(pk=container_2.pk).count(), 0) +        self.assertEqual(models.Container.objects.filter(pk=container_2.pk).count(), 0)          # preserve existing fields -        self.assertEqual(container_1.reference, 'Test 1') +        self.assertEqual(container_1.reference, "Test 1")          self.assertEqual(container_1.container_type, ct)          find_lst = [f for f in container_1.finds.all()]          for f in [find0, find1, find2]: @@ -889,17 +878,15 @@ class ContainerTest(FindInit, TestCase):          find3 = self.finds[3]          top_container_1 = models.Container.objects.create( -            reference="Topref 1", -            location=self.main_warehouse, -            container_type=ct) +            reference="Topref 1", location=self.main_warehouse, container_type=ct +        )          find0.container = top_container_1          find0.container_ref = top_container_1          find0.save()          top_container_2 = models.Container.objects.create( -            reference="Topref 2", -            location=self.alt_warehouse, -            container_type=ct) +            reference="Topref 2", location=self.alt_warehouse, container_type=ct +        )          find1.container = top_container_2          find1.container_ref = top_container_2          find1.save() @@ -908,7 +895,8 @@ class ContainerTest(FindInit, TestCase):              reference="Middle ref",              location=self.main_warehouse,              parent=top_container_1, -            container_type=ct2) +            container_type=ct2, +        )          find2.container = middle_container_1          find2.container_ref = middle_container_1          find2.save() @@ -917,13 +905,15 @@ class ContainerTest(FindInit, TestCase):              reference="Middle ref",              location=self.alt_warehouse,              parent=top_container_2, -            container_type=ct2) +            container_type=ct2, +        )          bottom_container_3 = models.Container.objects.create(              reference="Bottom ref",              location=self.alt_warehouse,              parent=middle_container_2, -            container_type=ct3) +            container_type=ct3, +        )          find3.container = bottom_container_3          find3.container_ref = bottom_container_3          find3.save() @@ -956,8 +946,7 @@ class ContainerTest(FindInit, TestCase):      def test_bulk_update(self):          username, password, user = create_user() -        user.user_permissions.add(Permission.objects.get( -            codename='change_container')) +        user.user_permissions.add(Permission.objects.get(codename="change_container"))          client = Client()          ct = models.ContainerType.objects.all()[0] @@ -966,34 +955,32 @@ class ContainerTest(FindInit, TestCase):          container_parent = models.Container.objects.create(              reference="Parent container",              location=self.main_warehouse, -            container_type=ct) +            container_type=ct, +        )          container_parent2 = models.Container.objects.create(              reference="Parent container 2",              location=self.alt_warehouse, -            container_type=ct) +            container_type=ct, +        )          container = models.Container.objects.create(              reference="Test",              location=self.main_warehouse,              parent=container_parent, -            container_type=ct2) +            container_type=ct2, +        )          # base modification -        url = reverse('container-qa-bulk-update', args=[container.pk]) -        data = { -            "qacontainer_type": ct.pk, -            "qalocation": '', -            "qaparent": '' -        } +        url = reverse("container-qa-bulk-update", args=[container.pk]) +        data = {"qacontainer_type": ct.pk, "qalocation": "", "qaparent": ""}          response = client.post(url, data) -        self.assertRedirects(response, '/') +        self.assertRedirects(response, "/")          client.login(username=username, password=password)          response = client.post(url, data)          self.assertEqual(response.status_code, 200) -        confirm_url = reverse( -            'container-qa-bulk-update-confirm', args=[container.pk]) +        confirm_url = reverse("container-qa-bulk-update-confirm", args=[container.pk])          response = client.post(confirm_url, data) -        self.assertRedirects(response, '/success/') +        self.assertRedirects(response, "/success/")          container = models.Container.objects.get(pk=container.pk)          self.assertEqual(container.container_type_id, ct.pk) @@ -1002,12 +989,12 @@ class ContainerTest(FindInit, TestCase):          container.save()          data = { -            "qacontainer_type": '', +            "qacontainer_type": "",              "qalocation": self.alt_warehouse.pk, -            "qaparent": container_parent2.pk +            "qaparent": container_parent2.pk,          }          response = client.post(confirm_url, data) -        self.assertRedirects(response, '/success/') +        self.assertRedirects(response, "/success/")          container = models.Container.objects.get(pk=container.pk)          self.assertEqual(container.location, self.alt_warehouse) @@ -1020,14 +1007,15 @@ class ContainerTest(FindInit, TestCase):          # change location of children          data = { -            "qacontainer_type": '', +            "qacontainer_type": "",              "qalocation": self.alt_warehouse.pk, -            "qaparent": '' +            "qaparent": "",          }          confirm_parent_url = reverse( -            'container-qa-bulk-update-confirm', args=[container_parent.pk]) +            "container-qa-bulk-update-confirm", args=[container_parent.pk] +        )          response = client.post(confirm_parent_url, data) -        self.assertRedirects(response, '/success/') +        self.assertRedirects(response, "/success/")          container_parent = models.Container.objects.get(pk=container_parent.pk)          self.assertEqual(container_parent.location, self.alt_warehouse) @@ -1043,12 +1031,12 @@ class ContainerTest(FindInit, TestCase):          # reinit parent when not provided and location changed          data = { -            "qacontainer_type": '', +            "qacontainer_type": "",              "qalocation": self.alt_warehouse.pk, -            "qaparent": '' +            "qaparent": "",          }          response = client.post(confirm_url, data) -        self.assertRedirects(response, '/success/') +        self.assertRedirects(response, "/success/")          container = models.Container.objects.get(pk=container.pk)          self.assertEqual(container.location, self.alt_warehouse)          self.assertEqual(container.parent, None) @@ -1061,44 +1049,41 @@ class ContainerTest(FindInit, TestCase):          ct2.stationary = True          ct2.save() -        q = models.Container.objects.filter( -            location=self.main_warehouse).order_by("-index") +        q = models.Container.objects.filter(location=self.main_warehouse).order_by( +            "-index" +        )          if q.count():              base_index = q.all()[0].index          else:              base_index = 0          container_1 = models.Container.objects.create( -            reference="Ref 1", -            location=self.main_warehouse, -            container_type=ct) -        self.assertEqual(models.Container.objects.get(pk=container_1.pk).index, -                         base_index + 1) +            reference="Ref 1", location=self.main_warehouse, container_type=ct +        ) +        self.assertEqual( +            models.Container.objects.get(pk=container_1.pk).index, base_index + 1 +        )          container_2 = models.Container.objects.create( -            reference="Ref 2", -            location=self.main_warehouse, -            container_type=ct) -        self.assertEqual(models.Container.objects.get(pk=container_2.pk).index, -                         base_index + 2) +            reference="Ref 2", location=self.main_warehouse, container_type=ct +        ) +        self.assertEqual( +            models.Container.objects.get(pk=container_2.pk).index, base_index + 2 +        )          container_3 = models.Container.objects.create( -            reference="Ref 3", -            location=self.main_warehouse, -            container_type=ct2) +            reference="Ref 3", location=self.main_warehouse, container_type=ct2 +        )          self.assertEqual(container_3.index, None) -        self.assertEqual(models.Container.objects.get(pk=container_3.pk).index, -                         None) +        self.assertEqual(models.Container.objects.get(pk=container_3.pk).index, None)          container_4 = models.Container.objects.create( -            reference="Ref 4", -            location=self.main_warehouse, -            container_type=ct2) +            reference="Ref 4", location=self.main_warehouse, container_type=ct2 +        )          self.assertEqual(container_4.index, None) -        self.assertEqual(models.Container.objects.get(pk=container_4.pk).index, -                         None) +        self.assertEqual(models.Container.objects.get(pk=container_4.pk).index, None)          container_5 = models.Container.objects.create( -            reference="Ref 5", -            location=self.main_warehouse, -            container_type=ct) -        self.assertEqual(models.Container.objects.get(pk=container_5.pk).index, -                         base_index + 3) +            reference="Ref 5", location=self.main_warehouse, container_type=ct +        ) +        self.assertEqual( +            models.Container.objects.get(pk=container_5.pk).index, base_index + 3 +        )      def test_get_material_types(self):          mat0 = MaterialType.objects.all()[0] @@ -1117,13 +1102,11 @@ class ContainerTest(FindInit, TestCase):          find2 = self.finds[2]          container_1 = models.Container.objects.create( -            reference="Test 1", -            location=self.main_warehouse, -            container_type=ct) +            reference="Test 1", location=self.main_warehouse, container_type=ct +        )          container_2 = models.Container.objects.create( -            reference="Test 2", -            location=self.alt_warehouse, -            container_type=ct) +            reference="Test 2", location=self.alt_warehouse, container_type=ct +        )          find0.container = container_1          find0.save()          find1.container = container_1 @@ -1133,16 +1116,16 @@ class ContainerTest(FindInit, TestCase):          find1.save()          # no material inside this container -        self.assertEqual( -            container_2.get_material_types(), "") +        self.assertEqual(container_2.get_material_types(), "")          self.assertEqual(              container_1.get_material_types(), -            ", ".join(sorted([mat0.label, mat1.label, mat2.label])) +            ", ".join(sorted([mat0.label, mat1.label, mat2.label])),          )          self.assertEqual(              container_1.get_material_types_code(), -            "|".join(sorted([mat0.code, mat1.code, mat2.code]))) +            "|".join(sorted([mat0.code, mat1.code, mat2.code])), +        )      def test_calculated_weight(self):          self.create_finds() @@ -1160,9 +1143,8 @@ class ContainerTest(FindInit, TestCase):          ct.tare_weight = 200          ct.save()          container_1 = models.Container.objects.create( -            reference="Test 1", -            location=self.main_warehouse, -            container_type=ct) +            reference="Test 1", location=self.main_warehouse, container_type=ct +        )          container_1.save()          self.assertEqual(container_1.calculated_weight, 200)          self.assertEqual(container_1.cached_weight, 200) @@ -1188,7 +1170,8 @@ class ContainerTest(FindInit, TestCase):          self.assertEqual(container_1.cached_weight, 1500)          profile, created = IshtarSiteProfile.objects.get_or_create( -            slug='default', active=True) +            slug="default", active=True +        )          profile.calculate_weight_on_full = True          profile.save() @@ -1210,4 +1193,3 @@ class ContainerTest(FindInit, TestCase):          container_1 = models.Container.objects.get(pk=container_1.pk)          self.assertEqual(container_1.calculated_weight, None)          self.assertEqual(container_1.cached_weight, None) - diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py index 46d812def..4a7ee9d09 100644 --- a/archaeological_warehouse/urls.py +++ b/archaeological_warehouse/urls.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2010-2016 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -28,112 +28,196 @@ from archaeological_warehouse import models  # forms  urlpatterns = [ -    url(r'warehouse_packaging/(?P<step>.+)?$',  # AFAC -        check_rights(['change_find', 'change_own_find'])( -        views.warehouse_packaging_wizard), name='warehouse_packaging'), - -    url(r'new-warehouse/(?P<parent_name>.+)?/$', -        views.new_warehouse, name='new-warehouse'), -    url(r'^show-warehouse(?:/(?P<pk>.+))?/(?P<type>.+)?$', views.show_warehouse, -        name=models.Warehouse.SHOW_URL), -    url(r'^show-historized-warehouse/(?P<pk>.+)?/(?P<date>.+)?$', -        views.show_warehouse, name='show-historized-warehouse'), -    url(r'^revert-warehouse/(?P<pk>.+)/(?P<date>.+)$', -        views.revert_warehouse, name='revert-warehouse'), -    url(r'autocomplete-warehouse/$', views.autocomplete_warehouse, -        name='autocomplete-warehouse'), -    url(r'new-container/(?P<parent_name>.+)?/$', -        views.new_container, name='new-container'), -    url(r'get-container/(?P<type>.+)?$', views.get_container, -        name='get-container'), -    url(r'get-divisions-container/(?P<type>.+)?$', -        views.get_divisions_container, name='get-divisions-container'), -    url(r'get-non-divisions-container/(?P<type>.+)?$', -        views.get_non_divisions_container, name='get-non-divisions-container'), -    url(r'get-warehouse/(?P<type>.+)?$', views.get_warehouse, -        name='get-warehouse'), -    url(r'get-warehouse-shortcut/(?P<type>.+)?$', -        views.get_warehouse, name='get-warehouse-shortcut', -        kwargs={'full': 'shortcut'}), -    url(r'autocomplete-container/(?P<warehouse_id>\d+)?(?:/)?$', -        views.autocomplete_container, name='autocomplete-container'), -    url(r'^show-container(?:/(?P<pk>.+))?/(?P<type>.+)?$', views.show_container, -        name=models.Container.SHOW_URL), -    url(r'^warehouse_search/(?P<step>.+)?$', -        check_rights(['view_warehouse', 'view_own_warehouse'])( -            views.warehouse_search_wizard), name='warehouse_search'), -    url(r'^warehouse_creation/(?P<step>.+)?$', -        check_rights(['add_warehouse'])( -            views.warehouse_creation_wizard), name='warehouse_creation'), -    url(r'^warehouse_modification/(?P<step>.+)?$', -        check_rights(['change_warehouse'])( -            views.warehouse_modification_wizard), -        name='warehouse_modification'), -    url(r'warehouse-modify/(?P<pk>.+)/$', -        views.warehouse_modify, name='warehouse_modify'), -    url(r'^warehouse_deletion/(?P<step>.+)?$', -        check_rights(['change_warehouse'])( -            views.warehouse_deletion_wizard), -        name='warehouse_deletion'), -    url(r'warehouse-delete/(?P<pk>.+)/$', -        views.warehouse_delete, name='delete-warehouse'), - -    url(r'^warehouse-qa-lock/(?P<pks>[0-9-]+)?/$', -        views.QAWarehouseLockView.as_view(), name='warehouse-qa-lock', -        kwargs={"model": models.Warehouse}), - -    url(r'^container-add-treatment/(?P<pk>[0-9-]+)/$', -        check_rights(['change_find', 'change_own_find'])( -            views.container_treatment_add), -        name='container-add-treatment'), - -    url(r'^container_search/(?P<step>.+)?$', -        check_rights(['view_container', 'view_own_container'])( -            views.container_search_wizard), -        name='container_search'), -    url(r'^container_creation/(?P<step>.+)?$', -        check_rights(['add_container', 'add_own_container'])( -            views.container_creation_wizard), -        name='container_creation'), -    url(r'^container_modification/(?P<step>.+)?$', -        check_rights(['change_container', 'change_own_container'])( -            views.container_modification_wizard), -        name='container_modification'), -    url(r'container-modify/(?P<pk>.+)/$', -        views.container_modify, name='container_modify'), -    url(r'^container_deletion/(?P<step>.+)?$', -        check_rights(['change_container', 'change_own_container'])( -            views.container_deletion_wizard), -        name='container_deletion'), -    url(r'container-delete/(?P<pk>.+)/$', -        views.container_delete, name='delete-container'), - -    url(r'^container-qa-bulk-update/(?P<pks>[0-9-]+)?/$', -        check_rights(['change_container', 'change_own_container'])( -            views.QAContainerForm.as_view()), -        name='container-qa-bulk-update'), -    url(r'^container-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$', -        check_rights(['change_container', 'change_own_container'])( -            views.QAContainerForm.as_view()), -        name='container-qa-bulk-update-confirm', kwargs={"confirm": True}), -    url(r'^container-qa-lock/(?P<pks>[0-9-]+)?/$', -        views.QAContainerLockView.as_view(), name='container-qa-lock', -        kwargs={"model": models.Container}), - -    url(r'container-merge/(?:(?P<page>\d+)/)?$', views.container_merge, -        name='container_merge'), -    url(r'container-manual-merge/$', +    url( +        r"warehouse_packaging/(?P<step>.+)?$",  # AFAC +        check_rights(["change_find", "change_own_find"])( +            views.warehouse_packaging_wizard +        ), +        name="warehouse_packaging", +    ), +    url( +        r"new-warehouse/(?P<parent_name>.+)?/$", +        views.new_warehouse, +        name="new-warehouse", +    ), +    url( +        r"^show-warehouse(?:/(?P<pk>.+))?/(?P<type>.+)?$", +        views.show_warehouse, +        name=models.Warehouse.SHOW_URL, +    ), +    url( +        r"^show-historized-warehouse/(?P<pk>.+)?/(?P<date>.+)?$", +        views.show_warehouse, +        name="show-historized-warehouse", +    ), +    url( +        r"^revert-warehouse/(?P<pk>.+)/(?P<date>.+)$", +        views.revert_warehouse, +        name="revert-warehouse", +    ), +    url( +        r"autocomplete-warehouse/$", +        views.autocomplete_warehouse, +        name="autocomplete-warehouse", +    ), +    url( +        r"new-container/(?P<parent_name>.+)?/$", +        views.new_container, +        name="new-container", +    ), +    url(r"get-container/(?P<type>.+)?$", views.get_container, name="get-container"), +    url( +        r"get-divisions-container/(?P<type>.+)?$", +        views.get_divisions_container, +        name="get-divisions-container", +    ), +    url( +        r"get-non-divisions-container/(?P<type>.+)?$", +        views.get_non_divisions_container, +        name="get-non-divisions-container", +    ), +    url(r"get-warehouse/(?P<type>.+)?$", views.get_warehouse, name="get-warehouse"), +    url( +        r"get-warehouse-shortcut/(?P<type>.+)?$", +        views.get_warehouse, +        name="get-warehouse-shortcut", +        kwargs={"full": "shortcut"}, +    ), +    url( +        r"autocomplete-container/(?P<warehouse_id>\d+)?(?:/)?$", +        views.autocomplete_container, +        name="autocomplete-container", +    ), +    url( +        r"^show-container(?:/(?P<pk>.+))?/(?P<type>.+)?$", +        views.show_container, +        name=models.Container.SHOW_URL, +    ), +    url( +        r"^warehouse_search/(?P<step>.+)?$", +        check_rights(["view_warehouse", "view_own_warehouse"])( +            views.warehouse_search_wizard +        ), +        name="warehouse_search", +    ), +    url( +        r"^warehouse_creation/(?P<step>.+)?$", +        check_rights(["add_warehouse"])(views.warehouse_creation_wizard), +        name="warehouse_creation", +    ), +    url( +        r"^warehouse_modification/(?P<step>.+)?$", +        check_rights(["change_warehouse"])(views.warehouse_modification_wizard), +        name="warehouse_modification", +    ), +    url( +        r"warehouse-modify/(?P<pk>.+)/$", +        views.warehouse_modify, +        name="warehouse_modify", +    ), +    url( +        r"^warehouse_deletion/(?P<step>.+)?$", +        check_rights(["change_warehouse"])(views.warehouse_deletion_wizard), +        name="warehouse_deletion", +    ), +    url( +        r"warehouse-delete/(?P<pk>.+)/$", +        views.warehouse_delete, +        name="delete-warehouse", +    ), +    url( +        r"^warehouse-qa-lock/(?P<pks>[0-9-]+)?/$", +        views.QAWarehouseLockView.as_view(), +        name="warehouse-qa-lock", +        kwargs={"model": models.Warehouse}, +    ), +    url( +        r"^container-add-treatment/(?P<pk>[0-9-]+)/$", +        check_rights(["change_find", "change_own_find"])(views.container_treatment_add), +        name="container-add-treatment", +    ), +    url( +        r"^container_search/(?P<step>.+)?$", +        check_rights(["view_container", "view_own_container"])( +            views.container_search_wizard +        ), +        name="container_search", +    ), +    url( +        r"^container_creation/(?P<step>.+)?$", +        check_rights(["add_container", "add_own_container"])( +            views.container_creation_wizard +        ), +        name="container_creation", +    ), +    url( +        r"^container_modification/(?P<step>.+)?$", +        check_rights(["change_container", "change_own_container"])( +            views.container_modification_wizard +        ), +        name="container_modification", +    ), +    url( +        r"container-modify/(?P<pk>.+)/$", +        views.container_modify, +        name="container_modify", +    ), +    url( +        r"^container_deletion/(?P<step>.+)?$", +        check_rights(["change_container", "change_own_container"])( +            views.container_deletion_wizard +        ), +        name="container_deletion", +    ), +    url( +        r"container-delete/(?P<pk>.+)/$", +        views.container_delete, +        name="delete-container", +    ), +    url( +        r"^container-qa-bulk-update/(?P<pks>[0-9-]+)?/$", +        check_rights(["change_container", "change_own_container"])( +            views.QAContainerForm.as_view() +        ), +        name="container-qa-bulk-update", +    ), +    url( +        r"^container-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", +        check_rights(["change_container", "change_own_container"])( +            views.QAContainerForm.as_view() +        ), +        name="container-qa-bulk-update-confirm", +        kwargs={"confirm": True}, +    ), +    url( +        r"^container-qa-lock/(?P<pks>[0-9-]+)?/$", +        views.QAContainerLockView.as_view(), +        name="container-qa-lock", +        kwargs={"model": models.Container}, +    ), +    url( +        r"container-merge/(?:(?P<page>\d+)/)?$", +        views.container_merge, +        name="container_merge", +    ), +    url( +        r"container-manual-merge/$",          views.ContainerManualMerge.as_view(), -        name='container_manual_merge'), -    url(r'container-manual-merge-items/(?P<pks>[0-9_]+?)/$', +        name="container_manual_merge", +    ), +    url( +        r"container-manual-merge-items/(?P<pks>[0-9_]+?)/$",          views.ContainerManualMergeItems.as_view(), -        name='container_manual_merge_items'), - -    url(r'generate-stats-container/(?P<pk>.+)/', +        name="container_manual_merge_items", +    ), +    url( +        r"generate-stats-container/(?P<pk>.+)/",          views.GenerateStatsContainer.as_view(), -        name='generate-stats-container'), - -    url(r'generate-stats-warehouse/(?P<pk>.+)/', +        name="generate-stats-container", +    ), +    url( +        r"generate-stats-warehouse/(?P<pk>.+)/",          views.GenerateStatsWarehouse.as_view(), -        name='generate-stats-warehouse'), +        name="generate-stats-warehouse", +    ),  ] diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index 2702e71c3..4fa60ff89 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2010-2016  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -32,72 +32,97 @@ from archaeological_warehouse import forms  from ishtar_common.forms import FinalForm -from ishtar_common.views import QABaseLockView, wizard_is_available, \ -    merge_action, ManualMergeMixin, ManualMergeItemsMixin, IshtarMixin, \ -    LoginRequiredMixin, QAItemEditForm -from ishtar_common.views_item import get_item, show_item, new_qa_item, \ -    revert_item +from ishtar_common.views import ( +    QABaseLockView, +    wizard_is_available, +    merge_action, +    ManualMergeMixin, +    ManualMergeItemsMixin, +    IshtarMixin, +    LoginRequiredMixin, +    QAItemEditForm, +) +from ishtar_common.views_item import get_item, show_item, new_qa_item, revert_item  from archaeological_finds.views import treatment_add -from archaeological_warehouse.wizards import PackagingWizard, WarehouseSearch, \ -    WarehouseWizard, WarehouseModificationWizard, WarehouseDeletionWizard, \ -    ContainerSearch, ContainerWizard, ContainerModificationWizard, \ -    ContainerDeletionWizard +from archaeological_warehouse.wizards import ( +    PackagingWizard, +    WarehouseSearch, +    WarehouseWizard, +    WarehouseModificationWizard, +    WarehouseDeletionWizard, +    ContainerSearch, +    ContainerWizard, +    ContainerModificationWizard, +    ContainerDeletionWizard, +) -get_container = get_item(models.Container, 'get_container', 'container', -                         search_form=forms.ContainerSelect) +get_container = get_item( +    models.Container, "get_container", "container", search_form=forms.ContainerSelect +)  get_divisions_container = get_item( -    models.Container, 'get_container', 'container', +    models.Container, +    "get_container", +    "container",      search_form=forms.ContainerSelect, -    base_request={"container_type__stationary": 'True'}) +    base_request={"container_type__stationary": "True"}, +)  get_non_divisions_container = get_item( -    models.Container, 'get_container', 'container', +    models.Container, +    "get_container", +    "container",      search_form=forms.ContainerSelect, -    base_request={"container_type__stationary": 'False'}) -show_container = show_item(models.Container, 'container') +    base_request={"container_type__stationary": "False"}, +) +show_container = show_item(models.Container, "container") -get_warehouse = get_item(models.Warehouse, 'get_warehouse', 'warehouse', -                         search_form=forms.WarehouseSelect) -show_warehouse = show_item(models.Warehouse, 'warehouse') +get_warehouse = get_item( +    models.Warehouse, "get_warehouse", "warehouse", search_form=forms.WarehouseSelect +) +show_warehouse = show_item(models.Warehouse, "warehouse")  revert_warehouse = revert_item(models.Warehouse) -new_warehouse = new_qa_item(models.Warehouse, forms.WarehouseForm, -                            page_name=_("New warehouse")) -new_container = new_qa_item(models.Container, forms.ContainerForm, -                            page_name=_("New container")) +new_warehouse = new_qa_item( +    models.Warehouse, forms.WarehouseForm, page_name=_("New warehouse") +) +new_container = new_qa_item( +    models.Container, forms.ContainerForm, page_name=_("New container") +)  def autocomplete_warehouse(request): -    if not request.user.has_perm('ishtar_common.view_warehouse', -                                 models.Warehouse)\ -       and not request.user.has_perm( -            'ishtar_common.view_own_warehouse', models.Warehouse): -        return HttpResponse(content_type='text/plain') -    if not request.GET.get('term'): -        return HttpResponse(content_type='text/plain') -    q = request.GET.get('term') +    if not request.user.has_perm( +        "ishtar_common.view_warehouse", models.Warehouse +    ) and not request.user.has_perm( +        "ishtar_common.view_own_warehouse", models.Warehouse +    ): +        return HttpResponse(content_type="text/plain") +    if not request.GET.get("term"): +        return HttpResponse(content_type="text/plain") +    q = request.GET.get("term")      query = Q() -    for q in q.split(' '): -        extra = Q(name__icontains=q) | \ -            Q(warehouse_type__label__icontains=q) +    for q in q.split(" "): +        extra = Q(name__icontains=q) | Q(warehouse_type__label__icontains=q)          query = query & extra      limit = 15      warehouses = models.Warehouse.objects.filter(query)[:limit] -    data = json.dumps([{'id': warehouse.pk, 'value': str(warehouse)} -                       for warehouse in warehouses]) -    return HttpResponse(data, content_type='text/plain') +    data = json.dumps( +        [{"id": warehouse.pk, "value": str(warehouse)} for warehouse in warehouses] +    ) +    return HttpResponse(data, content_type="text/plain")  def autocomplete_container(request, warehouse_id=None): -    if not request.user.has_perm('ishtar_common.view_warehouse', -                                 models.Warehouse)\ -       and not request.user.has_perm( -            'ishtar_common.view_own_warehouse', models.Warehouse): -        return HttpResponse(content_type='text/plain') -    if not request.GET.get('term'): -        return HttpResponse(content_type='text/plain') -    term = request.GET.get('term').strip() +    if not request.user.has_perm( +        "ishtar_common.view_warehouse", models.Warehouse +    ) and not request.user.has_perm( +        "ishtar_common.view_own_warehouse", models.Warehouse +    ): +        return HttpResponse(content_type="text/plain") +    if not request.GET.get("term"): +        return HttpResponse(content_type="text/plain") +    term = request.GET.get("term").strip()      limit = 15      base_query = Q()      if warehouse_id: @@ -106,16 +131,18 @@ def autocomplete_container(request, warehouse_id=None):      # exact index      try:          query = query & Q(index=int(term)) -        containers = list(models.Container.objects.filter( -            query).values('id', 'cached_label')[:limit]) +        containers = list( +            models.Container.objects.filter(query).values("id", "cached_label")[:limit] +        )      except ValueError:          containers = []      # exact ref      query = query & Q(reference__unaccent__iexact=term) -    containers += list(models.Container.objects.filter( -        query).values('id', 'cached_label')[:limit]) +    containers += list( +        models.Container.objects.filter(query).values("id", "cached_label")[:limit] +    )      limit = 15 - len(containers) -    splitted = [s.lower() for s in term.split(' ') if s and s != '|'] +    splitted = [s.lower() for s in term.split(" ") if s and s != "|"]      if limit > 0 and len(splitted) > 1:          type_positions = []  # container_type ID, pos inf, pos sup @@ -147,7 +174,8 @@ def autocomplete_container(request, warehouse_id=None):                              index = None                  if index_is_ok:                      type_positions.append( -                        (container_type_id, index, index + len(values))) +                        (container_type_id, index, index + len(values)) +                    )          query = base_query          if not warehouse_id and type_positions and type_positions[0][1] > 0: @@ -155,12 +183,11 @@ def autocomplete_container(request, warehouse_id=None):                  query &= Q(location__name__icontains=splitted[idx])          # group by container type, ref tuple          groups = [] -        for idx, (container_type_id, pos_inf, pos_sup) \ -                in enumerate(type_positions): +        for idx, (container_type_id, pos_inf, pos_sup) in enumerate(type_positions):              if len(type_positions) == idx + 1:  # last                  value = " ".join(splitted[pos_sup:])              else: -                value = " ".join(splitted[pos_sup:type_positions[idx + 1][1]]) +                value = " ".join(splitted[pos_sup : type_positions[idx + 1][1]])              if value:                  groups.append((container_type_id, value))          if groups: @@ -171,9 +198,11 @@ def autocomplete_container(request, warehouse_id=None):                  key2 = base_key + "reference__unaccent__iexact"                  query &= Q(**{key1: g[0], key2: g[1]})              ids = {c["id"] for c in containers} -            containers += list(models.Container.objects.filter( -                query).exclude(pk__in=ids).values('id', 'cached_label')[ -                               :limit]) +            containers += list( +                models.Container.objects.filter(query) +                .exclude(pk__in=ids) +                .values("id", "cached_label")[:limit] +            )      if len(splitted) > 1 and len(containers) < 15:          # group to do a "type" "reference" search @@ -182,12 +211,15 @@ def autocomplete_container(request, warehouse_id=None):              group_2 = splitted[idx:]              extra = Q(                  container_type__label__unaccent__iexact=" ".join(group_1), -                reference__unaccent__iexact=" ".join(group_2)) +                reference__unaccent__iexact=" ".join(group_2), +            )              query = base_query & extra              ids = {c["id"] for c in containers} -            containers += list(models.Container.objects.filter( -                query).exclude(pk__in=ids).values('id', 'cached_label')[ -                               :limit]) +            containers += list( +                models.Container.objects.filter(query) +                .exclude(pk__in=ids) +                .values("id", "cached_label")[:limit] +            )              if len(containers) >= 15:                  break @@ -197,92 +229,114 @@ def autocomplete_container(request, warehouse_id=None):              extra = Q(reference__unaccent__iexact=q)              query = query & extra          ids = {c["id"] for c in containers} -        containers += list(models.Container.objects.filter( -            query).exclude(pk__in=ids).values('id', 'cached_label')[:limit]) +        containers += list( +            models.Container.objects.filter(query) +            .exclude(pk__in=ids) +            .values("id", "cached_label")[:limit] +        )          limit = 15 - len(containers)          if limit > 0:              query = base_query              for q in splitted: -                extra = Q(container_type__label__unaccent__icontains=q) | \ -                    Q(container_type__reference__unaccent__icontains=q) | \ -                    Q(reference__unaccent__icontains=q) | \ -                    Q(cached_label__unaccent__icontains=q) +                extra = ( +                    Q(container_type__label__unaccent__icontains=q) +                    | Q(container_type__reference__unaccent__icontains=q) +                    | Q(reference__unaccent__icontains=q) +                    | Q(cached_label__unaccent__icontains=q) +                )                  if not warehouse_id:                      extra |= Q(location__name__unaccent=q) | Q( -                        location__town__unaccent=q) +                        location__town__unaccent=q +                    )                  query = query & extra              ids = {c["id"] for c in containers}              containers += list( -                models.Container.objects.filter(query).exclude( -                    pk__in=ids -                ).values('id', 'cached_label')[:limit]) +                models.Container.objects.filter(query) +                .exclude(pk__in=ids) +                .values("id", "cached_label")[:limit] +            )      data = json.dumps( -        [{'id': container['id'], 'value': container['cached_label']} -         for container in containers]) -    return HttpResponse(data, content_type='text/plain') - -warehouse_packaging_wizard = PackagingWizard.as_view([  # AFAC -    ('seleccontainer-packaging', forms.ContainerFormSelection), -    ('base-packaging', forms.BasePackagingForm), -    ('final-packaging', FinalForm)], +        [ +            {"id": container["id"], "value": container["cached_label"]} +            for container in containers +        ] +    ) +    return HttpResponse(data, content_type="text/plain") + + +warehouse_packaging_wizard = PackagingWizard.as_view( +    [  # AFAC +        ("seleccontainer-packaging", forms.ContainerFormSelection), +        ("base-packaging", forms.BasePackagingForm), +        ("final-packaging", FinalForm), +    ],      label=_("Packaging"), -    url_name='warehouse_packaging',) +    url_name="warehouse_packaging", +) -warehouse_search_wizard = WarehouseSearch.as_view([ -    ('selec-warehouse_search', forms.WarehouseFormSelection)], +warehouse_search_wizard = WarehouseSearch.as_view( +    [("selec-warehouse_search", forms.WarehouseFormSelection)],      label=_("Warehouse search"), -    url_name='warehouse_search', +    url_name="warehouse_search",  )  warehouse_creation_steps = [      ("warehouse-warehouse_creation", forms.WarehouseForm), -    ('divisions-warehouse_creation', forms.SelectedDivisionFormset), -    ('final-warehouse_creation', FinalForm)] +    ("divisions-warehouse_creation", forms.SelectedDivisionFormset), +    ("final-warehouse_creation", FinalForm), +]  warehouse_creation_wizard = WarehouseWizard.as_view(      warehouse_creation_steps,      label=_("Warehouse creation"), -    url_name='warehouse_creation', +    url_name="warehouse_creation",  ) -warehouse_modification_wizard = WarehouseModificationWizard.as_view([ -    ('selec-warehouse_modification', forms.WarehouseFormSelection), -    ("warehouse-warehouse_modification", forms.WarehouseModifyForm), -    ('divisions-warehouse_modification', forms.SelectedDivisionFormset), -    ('final-warehouse_modification', FinalForm)], +warehouse_modification_wizard = WarehouseModificationWizard.as_view( +    [ +        ("selec-warehouse_modification", forms.WarehouseFormSelection), +        ("warehouse-warehouse_modification", forms.WarehouseModifyForm), +        ("divisions-warehouse_modification", forms.SelectedDivisionFormset), +        ("final-warehouse_modification", FinalForm), +    ],      label=_("Warehouse modification"), -    url_name='warehouse_modification', +    url_name="warehouse_modification",  )  def warehouse_modify(request, pk): -    if not wizard_is_available(warehouse_modification_wizard, request, -                               models.Warehouse, pk): +    if not wizard_is_available( +        warehouse_modification_wizard, request, models.Warehouse, pk +    ):          return HttpResponseRedirect("/") -    wizard_url = 'warehouse_modification' +    wizard_url = "warehouse_modification"      WarehouseModificationWizard.session_set_value( -        request, 'selec-' + wizard_url, 'pk', pk, reset=True) -    return redirect( -        reverse(wizard_url, kwargs={'step': 'warehouse-' + wizard_url})) +        request, "selec-" + wizard_url, "pk", pk, reset=True +    ) +    return redirect(reverse(wizard_url, kwargs={"step": "warehouse-" + wizard_url})) -warehouse_deletion_wizard = WarehouseDeletionWizard.as_view([ -    ('selec-warehouse_deletion', forms.WarehouseFormMultiSelection), -    ('final-warehouse_deletion', forms.WarehouseDeletionForm)], +warehouse_deletion_wizard = WarehouseDeletionWizard.as_view( +    [ +        ("selec-warehouse_deletion", forms.WarehouseFormMultiSelection), +        ("final-warehouse_deletion", forms.WarehouseDeletionForm), +    ],      label=_("Warehouse deletion"), -    url_name='warehouse_deletion',) +    url_name="warehouse_deletion", +)  def warehouse_delete(request, pk): -    if not wizard_is_available(warehouse_deletion_wizard, request, -                               models.Warehouse, pk): +    if not wizard_is_available( +        warehouse_deletion_wizard, request, models.Warehouse, pk +    ):          return HttpResponseRedirect("/") -    wizard_url = 'warehouse_deletion' +    wizard_url = "warehouse_deletion"      WarehouseDeletionWizard.session_set_value( -        request, 'selec-' + wizard_url, 'pks', pk, reset=True) -    return redirect( -        reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) +        request, "selec-" + wizard_url, "pks", pk, reset=True +    ) +    return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url}))  class QAWarehouseLockView(QABaseLockView): @@ -290,58 +344,66 @@ class QAWarehouseLockView(QABaseLockView):      base_url = "warehouse-qa-lock" -container_search_wizard = ContainerSearch.as_view([ -    ('selec-container_search', forms.MainContainerFormSelection)], +container_search_wizard = ContainerSearch.as_view( +    [("selec-container_search", forms.MainContainerFormSelection)],      label=_("Container search"), -    url_name='container_search', +    url_name="container_search",  )  container_creation_steps = [ -    ('container-container_creation', forms.ContainerForm), -    ('final-container_creation', FinalForm)] +    ("container-container_creation", forms.ContainerForm), +    ("final-container_creation", FinalForm), +]  container_creation_wizard = ContainerWizard.as_view(      container_creation_steps,      label=_("Container creation"), -    url_name='container_creation', +    url_name="container_creation",  ) -container_modification_wizard = ContainerModificationWizard.as_view([ -    ('selec-container_modification', forms.MainContainerFormSelection), -    ('container-container_modification', forms.ContainerModifyForm), -    ('final-container_modification', FinalForm)], +container_modification_wizard = ContainerModificationWizard.as_view( +    [ +        ("selec-container_modification", forms.MainContainerFormSelection), +        ("container-container_modification", forms.ContainerModifyForm), +        ("final-container_modification", FinalForm), +    ],      label=_("Container modification"), -    url_name='container_modification', +    url_name="container_modification",  )  def container_modify(request, pk): -    if not wizard_is_available(container_modification_wizard, request, -                               models.Container, pk): +    if not wizard_is_available( +        container_modification_wizard, request, models.Container, pk +    ):          return HttpResponseRedirect("/") -    wizard_url = 'container_modification' +    wizard_url = "container_modification"      ContainerModificationWizard.session_set_value( -        request, 'selec-' + wizard_url, 'pk', pk, reset=True) -    return redirect( -        reverse(wizard_url, kwargs={'step': 'container-' + wizard_url})) +        request, "selec-" + wizard_url, "pk", pk, reset=True +    ) +    return redirect(reverse(wizard_url, kwargs={"step": "container-" + wizard_url})) -container_deletion_wizard = ContainerDeletionWizard.as_view([ -    ('selec-container_deletion', forms.MainContainerFormMultiSelection), -    ('final-container_deletion', forms.ContainerDeletionForm)], +container_deletion_wizard = ContainerDeletionWizard.as_view( +    [ +        ("selec-container_deletion", forms.MainContainerFormMultiSelection), +        ("final-container_deletion", forms.ContainerDeletionForm), +    ],      label=_("Container deletion"), -    url_name='container_deletion',) +    url_name="container_deletion", +)  def container_delete(request, pk): -    if not wizard_is_available(container_deletion_wizard, request, -                               models.Container, pk): +    if not wizard_is_available( +        container_deletion_wizard, request, models.Container, pk +    ):          return HttpResponseRedirect("/") -    wizard_url = 'container_deletion' +    wizard_url = "container_deletion"      ContainerDeletionWizard.session_set_value( -        request, 'selec-' + wizard_url, 'pks', pk, reset=True) -    return redirect( -        reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) +        request, "selec-" + wizard_url, "pks", pk, reset=True +    ) +    return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url}))  def container_treatment_add(request, pk, current_right=None): @@ -349,9 +411,8 @@ def container_treatment_add(request, pk, current_right=None):          container = models.Container.objects.get(pk=pk)      except models.Container.DoesNotExist:          raise Http404() -    return treatment_add( -        request, ",".join(str(f.pk) for f in container.finds.all()) -    ) +    return treatment_add(request, ",".join(str(f.pk) for f in container.finds.all())) +  """  warehouse_packaging_wizard = ItemSourceWizard.as_view([ @@ -361,26 +422,27 @@ warehouse_packaging_wizard = ItemSourceWizard.as_view([  """ -container_merge = merge_action(models.Container, forms.MergeContainerForm, -                               'container', name_key="reference") +container_merge = merge_action( +    models.Container, forms.MergeContainerForm, "container", name_key="reference" +) -class ContainerManualMerge(ManualMergeMixin, IshtarMixin, LoginRequiredMixin, -                           FormView): +class ContainerManualMerge(ManualMergeMixin, IshtarMixin, LoginRequiredMixin, FormView):      form_class = forms.ContainerMergeFormSelection -    template_name = 'ishtar/form.html' +    template_name = "ishtar/form.html"      page_name = _("Merge containers") -    current_url = 'container-manual-merge' -    redir_url = 'container_manual_merge_items' +    current_url = "container-manual-merge" +    redir_url = "container_manual_merge_items" -class ContainerManualMergeItems(ManualMergeItemsMixin, IshtarMixin, -                                LoginRequiredMixin, FormView): +class ContainerManualMergeItems( +    ManualMergeItemsMixin, IshtarMixin, LoginRequiredMixin, FormView +):      form_class = forms.ContainerMergeIntoForm -    template_name = 'ishtar/form.html' +    template_name = "ishtar/form.html"      page_name = _("Select the main container") -    current_url = 'container-manual-merge-items' -    item_type = 'container' +    current_url = "container-manual-merge-items" +    item_type = "container"  class QAContainerLockView(QABaseLockView): @@ -390,13 +452,13 @@ class QAContainerLockView(QABaseLockView):  def reset_wizards(request):      for wizard_class, url_name in ( -            (PackagingWizard, 'warehouse_packaging'), -            (WarehouseWizard, 'warehouse_creation'), -            (WarehouseModificationWizard, 'warehouse_modification'), -            (WarehouseDeletionWizard, 'warehouse_deletion'), -            (ContainerWizard, 'container_creation'), -            (ContainerModificationWizard, 'container_modification'), -            (ContainerDeletionWizard, 'container_deletion'), +        (PackagingWizard, "warehouse_packaging"), +        (WarehouseWizard, "warehouse_creation"), +        (WarehouseModificationWizard, "warehouse_modification"), +        (WarehouseDeletionWizard, "warehouse_deletion"), +        (ContainerWizard, "container_creation"), +        (ContainerModificationWizard, "container_modification"), +        (ContainerDeletionWizard, "container_deletion"),      ):          wizard_class.session_reset(request, url_name) @@ -408,7 +470,7 @@ class QAContainerForm(QAItemEditForm):      def get_form_kwargs(self):          kwargs = super(QAContainerForm, self).get_form_kwargs()          # item list is necessary to verify uniqueness rules -        kwargs['items'] = self.items +        kwargs["items"] = self.items          return kwargs @@ -416,15 +478,16 @@ class GenerateStats(IshtarMixin, LoginRequiredMixin, RedirectView):      model = None      def get_redirect_url(self, *args, **kwargs): -        return reverse('display-item', -                       args=[self.model.SLUG, self.item.pk]) + "#stats" +        return reverse("display-item", args=[self.model.SLUG, self.item.pk]) + "#stats"      def get(self, request, *args, **kwargs): -        self.item = self.model.objects.get(pk=kwargs['pk']) -        self.item._get_or_set_stats('_number_of_finds_by_place', update=True, -                                    expected_type=list) -        self.item._get_or_set_stats('_number_of_containers_by_place', -                                    update=True, expected_type=list) +        self.item = self.model.objects.get(pk=kwargs["pk"]) +        self.item._get_or_set_stats( +            "_number_of_finds_by_place", update=True, expected_type=list +        ) +        self.item._get_or_set_stats( +            "_number_of_containers_by_place", update=True, expected_type=list +        )          return super(GenerateStats, self).get(request, *args, **kwargs) diff --git a/archaeological_warehouse/wizards.py b/archaeological_warehouse/wizards.py index 614e6e6be..66da94b86 100644 --- a/archaeological_warehouse/wizards.py +++ b/archaeological_warehouse/wizards.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012-2016  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -37,52 +37,54 @@ class ContainerSearch(SearchWizard):  class PackagingWizard(TreatmentWizard): -    basket_step = 'base-packaging' +    basket_step = "base-packaging"      def get_form_initial(self, step, data=None):          initial = super(PackagingWizard, self).get_form_initial(step)          user = self.request.user -        if step != 'base-packaging' or not getattr(user, 'ishtaruser', None) \ -                or not user.ishtaruser.person: +        if ( +            step != "base-packaging" +            or not getattr(user, "ishtaruser", None) +            or not user.ishtaruser.person +        ):              return initial -        initial['person'] = user.ishtaruser.person.pk +        initial["person"] = user.ishtaruser.person.pk          return initial -    def save_model(self, dct, m2m, whole_associated_models, form_list, -                   return_object): +    def save_model(self, dct, m2m, whole_associated_models, form_list, return_object):          dct = self.get_extra_model(dct, m2m, form_list)          obj = self.get_current_saved_object() -        dct['location'] = dct['container'].location +        dct["location"] = dct["container"].location          items = None -        if 'items' in dct: -            items = dct.pop('items') -        if 'basket' in dct: +        if "items" in dct: +            items = dct.pop("items") +        if "basket" in dct:              if not items: -                items = dct.pop('basket') +                items = dct.pop("basket")              else: -                dct.pop('basket') -        if 'treatment_type_list' in dct: -            dct.pop('treatment_type_list') +                dct.pop("basket") +        if "treatment_type_list" in dct: +            dct.pop("treatment_type_list")          treatment = Treatment(**dct) -        extra_args_for_new = {"container": dct['container']} -        treatment.save(items=items, user=self.request.user, -                       extra_args_for_new=extra_args_for_new) -        packaging = TreatmentType.objects.get(txt_idx='packaging') +        extra_args_for_new = {"container": dct["container"]} +        treatment.save( +            items=items, user=self.request.user, extra_args_for_new=extra_args_for_new +        ) +        packaging = TreatmentType.objects.get(txt_idx="packaging")          treatment.treatment_types.add(packaging) -        res = render(self.request, 'ishtar/wizard/wizard_done.html', {}) +        res = render(self.request, "ishtar/wizard/wizard_done.html", {})          return return_object and (obj, res) or res  class WarehouseWizard(Wizard):      model = models.Warehouse -    wizard_done_window = reverse_lazy('show-warehouse') +    wizard_done_window = reverse_lazy("show-warehouse")      redirect_url = "warehouse_modification" -    def save_model(self, dct, m2m, whole_associated_models, form_list, -                   return_object): +    def save_model(self, dct, m2m, whole_associated_models, form_list, return_object):          create_organization = False -        if 'create_organization' in dct: -            create_organization = dct.pop('create_organization') +        if "create_organization" in dct: +            create_organization = dct.pop("create_organization")          obj, res = super(WarehouseWizard, self).save_model(              dct, m2m, whole_associated_models, form_list, True          ) @@ -95,10 +97,9 @@ class WarehouseWizard(Wizard):  class WarehouseModificationWizard(Wizard):      model = models.Warehouse      modification = True -    wizard_done_window = reverse_lazy('show-warehouse') +    wizard_done_window = reverse_lazy("show-warehouse")      wizard_templates = { -        'divisions-warehouse_modification': -            'ishtar/wizard/wizard_warehouse_divisions.html', +        "divisions-warehouse_modification": "ishtar/wizard/wizard_warehouse_divisions.html",      }      redirect_url = "warehouse_modification" @@ -111,28 +112,26 @@ class WarehouseDeletionWizard(MultipleDeletionWizard):  class ContainerWizard(Wizard):      model = models.Container      wizard_templates = { -        'container-container_creation': -            'ishtar/wizard/wizard_container.html', -        'container-container_modification': -            'ishtar/wizard/wizard_container.html', +        "container-container_creation": "ishtar/wizard/wizard_container.html", +        "container-container_modification": "ishtar/wizard/wizard_container.html",      } -    ignore_init_steps = ['localisation'] -    wizard_done_window = reverse_lazy('show-container') +    ignore_init_steps = ["localisation"] +    wizard_done_window = reverse_lazy("show-container")      redirect_url = "container_modification"      def get_form_kwargs(self, step=None):          kwargs = super(ContainerWizard, self).get_form_kwargs(step) -        if step == 'localisation-' + self.url_name: -            container_pk = self.session_get_value( -                'selec-' + self.url_name, 'pk') +        if step == "localisation-" + self.url_name: +            container_pk = self.session_get_value("selec-" + self.url_name, "pk")              q = models.Container.objects.filter(pk=container_pk)              if q.count(): -                kwargs['container'] = q.all()[0] +                kwargs["container"] = q.all()[0]              warehouse_pk = self.session_get_value( -                'container-' + self.url_name, 'location') +                "container-" + self.url_name, "location" +            )              q = models.Warehouse.objects.filter(pk=warehouse_pk)              if q.count(): -                kwargs['warehouse'] = q.all()[0] +                kwargs["warehouse"] = q.all()[0]          return kwargs      def done(self, form_list, **kwargs): @@ -144,22 +143,25 @@ class ContainerWizard(Wizard):          for idx, form in enumerate(form_list):              if not form.is_valid():                  return self.render(form) -            container = self.get_current_object() or \ -                hasattr(self, 'current_object') and self.current_object -            if container and form.prefix == 'localisation-' + self.url_name: +            container = ( +                self.get_current_object() +                or hasattr(self, "current_object") +                and self.current_object +            ) +            if container and form.prefix == "localisation-" + self.url_name:                  for div_name in form.cleaned_data:                      try:                          division = models.WarehouseDivisionLink.objects.get( -                            pk=div_name.split('_')[-1], -                            warehouse=container.location +                            pk=div_name.split("_")[-1], warehouse=container.location                          )  # check the localisation match with the container                      except models.WarehouseDivisionLink.DoesNotExist:                          return self.render(form) -                    localisation, created = \ -                        models.ContainerLocalisation.objects.get_or_create( -                            container=container, -                            division=division -                        ) +                    ( +                        localisation, +                        created, +                    ) = models.ContainerLocalisation.objects.get_or_create( +                        container=container, division=division +                    )                      localisation.reference = form.cleaned_data[div_name]                      localisation.save()              obj = container @@ -176,9 +178,15 @@ class ContainerModificationWizard(ContainerWizard):  class ContainerDeletionWizard(MultipleDeletionWizard):      model = models.Container -    fields = ['container_type', 'reference', 'comment', 'location', 'index', -              'cached_label'] +    fields = [ +        "container_type", +        "reference", +        "comment", +        "location", +        "index", +        "cached_label", +    ]      redirect_url = "container_deletion"      wizard_templates = { -        'final-container_deletion': -            'ishtar/wizard/wizard_container_deletion.html'} +        "final-container_deletion": "ishtar/wizard/wizard_container_deletion.html" +    }  | 
