diff options
Diffstat (limited to 'archaeological_operations/models.py')
| -rw-r--r-- | archaeological_operations/models.py | 2974 | 
1 files changed, 1685 insertions, 1289 deletions
| diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 653c8d495..128b04496 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -35,27 +35,57 @@ from django.db.models.signals import post_save, m2m_changed, post_delete  from django.forms import ValidationError  from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy -from ishtar_common.models import BaseHistorizedItem, Dashboard, \ -    DashboardFormItem, Document, DocumentTemplate, \ -    GeneralRecordRelations, GeneralRelationType, GeneralType, \ -    IshtarUser, LightHistorizedItem, \ -    OperationType, Organization, OwnPerms, Person, PersonType, \ -    post_delete_record_relation, post_save_cache, RelationItem, \ -    ShortMenuItem, SourceType, Town, ValueGetter, get_current_profile, \ -    document_attached_changed, HistoryModel, SearchAltName, \ -    GeoItem, CompleteIdentifierItem, SearchVectorConfig, DocumentItem, QuickAction, \ -    MainItem, HierarchicalType +from ishtar_common.models import ( +    BaseHistorizedItem, +    Dashboard, +    DashboardFormItem, +    Document, +    DocumentTemplate, +    GeneralRecordRelations, +    GeneralRelationType, +    GeneralType, +    IshtarUser, +    LightHistorizedItem, +    OperationType, +    Organization, +    OwnPerms, +    Person, +    PersonType, +    post_delete_record_relation, +    post_save_cache, +    RelationItem, +    ShortMenuItem, +    SourceType, +    Town, +    ValueGetter, +    get_current_profile, +    document_attached_changed, +    HistoryModel, +    SearchAltName, +    GeoItem, +    CompleteIdentifierItem, +    SearchVectorConfig, +    DocumentItem, +    QuickAction, +    MainItem, +    HierarchicalType, +)  from ishtar_common.models_common import Department, HistoricalRecords  from ishtar_common.model_managers import UUIDModelManager -from ishtar_common.utils import cached_label_changed, \ -    force_cached_label_changed, mode, m2m_historization_changed, post_save_geo +from ishtar_common.utils import ( +    cached_label_changed, +    force_cached_label_changed, +    mode, +    m2m_historization_changed, +    post_save_geo, +)  class RemainType(GeneralType):      class Meta:          verbose_name = _("Remain type")          verbose_name_plural = _("Remain types") -        ordering = ('label',) +        ordering = ("label",)  post_save.connect(post_save_cache, sender=RemainType) @@ -66,14 +96,18 @@ class Period(GeneralType):      order = models.IntegerField(_("Order"))      start_date = models.IntegerField(_("Start date"), null=True, blank=True)      end_date = models.IntegerField(_("End date"), null=True, blank=True) -    parent = models.ForeignKey("Period", verbose_name=_("Parent period"), -                               on_delete=models.SET_NULL, -                               blank=True, null=True) +    parent = models.ForeignKey( +        "Period", +        verbose_name=_("Parent period"), +        on_delete=models.SET_NULL, +        blank=True, +        null=True, +    )      class Meta:          verbose_name = _("Type Period")          verbose_name_plural = _("Types Period") -        ordering = ('order',) +        ordering = ("order",)      def __str__(self):          return self.label @@ -89,7 +123,7 @@ class ReportState(GeneralType):      class Meta:          verbose_name = _("Type of report state")          verbose_name_plural = _("Types of report state") -        ordering = ('order',) +        ordering = ("order",)  post_save.connect(post_save_cache, sender=ReportState) @@ -107,7 +141,7 @@ class RecordQualityType(GeneralType):      class Meta:          verbose_name = _("Type of record quality")          verbose_name_plural = _("Types of record quality") -        ordering = ('order',) +        ordering = ("order",)  class CulturalAttributionType(HierarchicalType): @@ -116,45 +150,58 @@ class CulturalAttributionType(HierarchicalType):      class Meta:          verbose_name = _("Cultural attribution type")          verbose_name_plural = _("Cultural attribution types") -        ordering = ('order',) +        ordering = ("order",)  post_save.connect(post_save_cache, sender=RecordQualityType)  post_delete.connect(post_save_cache, sender=RecordQualityType) -class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierItem, -                         GeoItem, OwnPerms, ValueGetter, MainItem): -    SLUG = 'site' +class ArchaeologicalSite( +    DocumentItem, +    BaseHistorizedItem, +    CompleteIdentifierItem, +    GeoItem, +    OwnPerms, +    ValueGetter, +    MainItem, +): +    SLUG = "site"      APP = "archaeological-operations"      MODEL = "archaeological-site" -    SHOW_URL = 'show-site' -    DELETE_URL = 'delete-site' -    TABLE_COLS = ['reference', 'name', 'cached_towns_label', -                  'cached_periods', 'cached_remains'] +    SHOW_URL = "show-site" +    DELETE_URL = "delete-site" +    TABLE_COLS = [ +        "reference", +        "name", +        "cached_towns_label", +        "cached_periods", +        "cached_remains", +    ]      NEW_QUERY_ENGINE = True      COL_LABELS = { -        'cached_towns_label': _("Towns"), -        'cached_periods': _("Periods"), -        'cached_remains': _("Remains"), +        "cached_towns_label": _("Towns"), +        "cached_periods": _("Periods"), +        "cached_remains": _("Remains"),      } -    LONG_SLUG = 'archaeologicalsite' - -    STATISTIC_MODALITIES_OPTIONS = OrderedDict([ -        ("towns__areas__label", _("Area")), -        ("towns__areas__parent__label", _("Extended area")), -        ("periods__label", _("Periods")), -        ("remains__label", _("Remains")), -        ("documents__source_type__label", _("Associated document type")), -    ]) -    STATISTIC_MODALITIES = [ -        key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()] +    LONG_SLUG = "archaeologicalsite" + +    STATISTIC_MODALITIES_OPTIONS = OrderedDict( +        [ +            ("towns__areas__label", _("Area")), +            ("towns__areas__parent__label", _("Extended area")), +            ("periods__label", _("Periods")), +            ("remains__label", _("Remains")), +            ("documents__source_type__label", _("Associated document type")), +        ] +    ) +    STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]      BASE_SEARCH_VECTORS = [ -        SearchVectorConfig("comment", 'local'), -        SearchVectorConfig("discovery_area", 'local'), -        SearchVectorConfig("locality_cadastral", 'local'), -        SearchVectorConfig("locality_ngi", 'local'), +        SearchVectorConfig("comment", "local"), +        SearchVectorConfig("discovery_area", "local"), +        SearchVectorConfig("locality_cadastral", "local"), +        SearchVectorConfig("locality_ngi", "local"),          SearchVectorConfig("name"),          SearchVectorConfig("oceanographic_service_localisation"),          SearchVectorConfig("reference"), @@ -169,207 +216,222 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          SearchVectorConfig("remains__label", "local"),          SearchVectorConfig("towns__name"),      ] -    PARENT_SEARCH_VECTORS = ['operations'] +    PARENT_SEARCH_VECTORS = ["operations"] -    DATED_FIELDS = ['sinking_date'] +    DATED_FIELDS = ["sinking_date"]      EXTRA_REQUEST_KEYS = { -        'towns_label': 'towns', -        'collaborators__pk': 'collaborators__pk',  # dynamic_table_documents -        'cached_towns_label': 'cached_towns_label', -        'cached_periods': 'cached_periods', -        'cached_remains': 'remains', +        "towns_label": "towns", +        "collaborators__pk": "collaborators__pk",  # dynamic_table_documents +        "cached_towns_label": "cached_towns_label", +        "cached_periods": "cached_periods", +        "cached_remains": "remains",      }      # alternative names of fields for searches      REVERSED_BOOL_FIELDS = [ -        'documents__image__isnull', -        'documents__associated_file__isnull', -        'documents__associated_url__isnull', +        "documents__image__isnull", +        "documents__associated_file__isnull", +        "documents__associated_url__isnull",      ]      ALT_NAMES = { -        'reference': SearchAltName( -            pgettext_lazy("key for text search", "reference"), -            'reference__iexact' +        "reference": SearchAltName( +            pgettext_lazy("key for text search", "reference"), "reference__iexact"          ), -        'name': SearchAltName( -            pgettext_lazy("key for text search", "name"), -            'name__iexact' +        "name": SearchAltName( +            pgettext_lazy("key for text search", "name"), "name__iexact"          ), -        'other_reference': SearchAltName( +        "other_reference": SearchAltName(              pgettext_lazy("key for text search", "other-reference"), -            'other_reference__iexact' +            "other_reference__iexact",          ), -        'periods': SearchAltName( -            pgettext_lazy("key for text search", "period"), -            'periods__label__iexact' +        "periods": SearchAltName( +            pgettext_lazy("key for text search", "period"), "periods__label__iexact"          ), -        'remains': SearchAltName( -            pgettext_lazy("key for text search", "remain"), -            'remains__label__iexact' +        "remains": SearchAltName( +            pgettext_lazy("key for text search", "remain"), "remains__label__iexact"          ), -        'towns': SearchAltName( -            pgettext_lazy("key for text search", "town"), -            'towns__cached_label__iexact' +        "towns": SearchAltName( +            pgettext_lazy("key for text search", "town"), "towns__cached_label__iexact"          ), -        'towns__areas': SearchAltName( -            pgettext_lazy("key for text search", "area"), -            'towns__areas__label__iexact' +        "towns__areas": SearchAltName( +            pgettext_lazy("key for text search", "area"), "towns__areas__label__iexact"          ), -        'comment': SearchAltName( -            pgettext_lazy("key for text search", "comment"), -            'comment__iexact' +        "comment": SearchAltName( +            pgettext_lazy("key for text search", "comment"), "comment__iexact"          ), -        'locality_ngi': SearchAltName( -            pgettext_lazy("key for text search", "locality-ngi"), -            'locality_ngi__iexact' +        "locality_ngi": SearchAltName( +            pgettext_lazy("key for text search", "locality-ngi"), "locality_ngi__iexact"          ), -        'locality_cadastral': SearchAltName( +        "locality_cadastral": SearchAltName(              pgettext_lazy("key for text search", "locality-cadastral"), -            'locality_cadastral__iexact' +            "locality_cadastral__iexact",          ), -        'shipwreck_name': SearchAltName( +        "shipwreck_name": SearchAltName(              pgettext_lazy("key for text search", "shipwreck-name"), -            'shipwreck_name__iexact' +            "shipwreck_name__iexact",          ), -        'oceanographic_service_localisation': SearchAltName( -            pgettext_lazy("key for text search", -                          "oceanographic-service-localisation"), -            'oceanographic_service_localisation__iexact' +        "oceanographic_service_localisation": SearchAltName( +            pgettext_lazy("key for text search", "oceanographic-service-localisation"), +            "oceanographic_service_localisation__iexact",          ), -        'shipwreck_code': SearchAltName( +        "shipwreck_code": SearchAltName(              pgettext_lazy("key for text search", "shipwreck-code"), -            'shipwreck_code__iexact' +            "shipwreck_code__iexact",          ), -        'sinking_date': SearchAltName( -            pgettext_lazy("key for text search", "sinking-date"), -            'sinking_date' +        "sinking_date": SearchAltName( +            pgettext_lazy("key for text search", "sinking-date"), "sinking_date"          ), -        'discovery_area': SearchAltName( +        "discovery_area": SearchAltName(              pgettext_lazy("key for text search", "discovery-area"), -            'discovery_area__iexact' +            "discovery_area__iexact",          ), -        'operation': SearchAltName( +        "operation": SearchAltName(              pgettext_lazy("key for text search", "operation"), -            'operations__cached_label__icontains' +            "operations__cached_label__icontains",          ), -        'top_operation': SearchAltName( +        "top_operation": SearchAltName(              pgettext_lazy("key for text search", "top-operation"), -            'top_operations__cached_label__icontains' +            "top_operations__cached_label__icontains",          ), -        'drassm_number': SearchAltName( +        "drassm_number": SearchAltName(              pgettext_lazy("key for text search", "numero-drassm"), -            'drassm_number__iexact' +            "drassm_number__iexact",          ), -        'affmar_number': SearchAltName( +        "affmar_number": SearchAltName(              pgettext_lazy("key for text search", "numero-affmar"), -            'affmar_number__iexact' +            "affmar_number__iexact",          ), -        'cultural_attributions': SearchAltName( +        "cultural_attributions": SearchAltName(              pgettext_lazy("key for text search", "cultural-attribution"), -            'cultural_attributions__label__iexact' +            "cultural_attributions__label__iexact",          ),      }      ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)      ALT_NAMES.update(DocumentItem.ALT_NAMES)      UP_MODEL_QUERY = { -        "operation": (pgettext_lazy("key for text search", "operation"), -                      'cached_label'), +        "operation": ( +            pgettext_lazy("key for text search", "operation"), +            "cached_label", +        ),      }      RELATIVE_SESSION_NAMES = [ -        ('operation', 'operations__pk'), +        ("operation", "operations__pk"), +    ] +    HISTORICAL_M2M = ["periods", "remains", "towns", "cultural_attributions"] +    CACHED_LABELS = [ +        "cached_label", +        "cached_towns_label", +        "cached_periods", +        "cached_remains",      ] -    HISTORICAL_M2M = ['periods', 'remains', 'towns', 'cultural_attributions'] -    CACHED_LABELS = ['cached_label', 'cached_towns_label', 'cached_periods', -                     'cached_remains']      DOWN_MODEL_UPDATE = ["context_records"]      QA_LOCK = QuickAction( -        url="site-qa-lock", icon_class="fa fa-lock", -        text=_("Lock/Unlock"), target="many", -        rights=['change_archaeologicalsite', -                'change_own_archaeologicalsite'] +        url="site-qa-lock", +        icon_class="fa fa-lock", +        text=_("Lock/Unlock"), +        target="many", +        rights=["change_archaeologicalsite", "change_own_archaeologicalsite"],      )      QA_EDIT = QuickAction( -        url="site-qa-bulk-update", icon_class="fa fa-pencil", -        text=_("Bulk update"), target="many", -        rights=['change_archaeologicalsite', -                'change_own_archaeologicalsite'] +        url="site-qa-bulk-update", +        icon_class="fa fa-pencil", +        text=_("Bulk update"), +        target="many", +        rights=["change_archaeologicalsite", "change_own_archaeologicalsite"],      )      QUICK_ACTIONS = [          QA_EDIT,          QA_LOCK,          QuickAction( -            url="site-qa-duplicate", icon_class="fa fa-clone", -            text=_("Duplicate"), target="one", -            rights=['change_archaeologicalsite', -                    'change_own_archaeologicalsite']), +            url="site-qa-duplicate", +            icon_class="fa fa-clone", +            text=_("Duplicate"), +            target="one", +            rights=["change_archaeologicalsite", "change_own_archaeologicalsite"], +        ),      ]      objects = SiteManager()      reference = models.CharField(_("Reference"), max_length=200, unique=True) -    other_reference = models.TextField(_("Other reference"), blank=True, -                                       default="") -    name = models.CharField(_("Name"), max_length=200, -                            null=True, blank=True) -    periods = models.ManyToManyField(Period, verbose_name=_("Periods"), -                                     blank=True) -    remains = models.ManyToManyField("RemainType", verbose_name=_('Remains'), -                                     blank=True) +    other_reference = models.TextField(_("Other reference"), blank=True, default="") +    name = models.CharField(_("Name"), max_length=200, null=True, blank=True) +    periods = models.ManyToManyField(Period, verbose_name=_("Periods"), blank=True) +    remains = models.ManyToManyField( +        "RemainType", verbose_name=_("Remains"), blank=True +    )      cultural_attributions = models.ManyToManyField( -        "CulturalAttributionType", verbose_name=_("Cultural attribution"), -        blank=True) -    towns = models.ManyToManyField(Town, verbose_name=_("Towns"), -                                   related_name='sites', blank=True) +        "CulturalAttributionType", verbose_name=_("Cultural attribution"), blank=True +    ) +    towns = models.ManyToManyField( +        Town, verbose_name=_("Towns"), related_name="sites", blank=True +    )      comment = models.TextField(_("Comment"), blank=True, default="")      locality_ngi = models.TextField( -        _("National Geographic Institute locality"), blank=True, default="") -    locality_cadastral = models.TextField(_("Cadastral locality"), blank=True, -                                          default="") +        _("National Geographic Institute locality"), blank=True, default="" +    ) +    locality_cadastral = models.TextField( +        _("Cadastral locality"), blank=True, default="" +    )      collaborators = models.ManyToManyField( -        Person, blank=True, verbose_name=_("Collaborators"), -        related_name='site_collaborator' +        Person, +        blank=True, +        verbose_name=_("Collaborators"), +        related_name="site_collaborator",      )      # underwater -    shipwreck_name = models.TextField( -        _("Shipwreck name"), blank=True, default="") +    shipwreck_name = models.TextField(_("Shipwreck name"), blank=True, default="")      oceanographic_service_localisation = models.TextField( -        _("Oceanographic service localisation"), blank=True, default="") -    shipwreck_code = models.TextField( -        _("Shipwreck code"), blank=True, default="") -    sinking_date = models.DateField( -        _("Sinking date"), null=True, blank=True) -    discovery_area = models.TextField( -        _("Discovery area"), blank=True, default="") -    affmar_number = models.CharField(_("AffMar number"), max_length=100, -                                     null=True, blank=True) -    drassm_number = models.CharField(_("DRASSM number"), max_length=100, -                                     null=True, blank=True) +        _("Oceanographic service localisation"), blank=True, default="" +    ) +    shipwreck_code = models.TextField(_("Shipwreck code"), blank=True, default="") +    sinking_date = models.DateField(_("Sinking date"), null=True, blank=True) +    discovery_area = models.TextField(_("Discovery area"), blank=True, default="") +    affmar_number = models.CharField( +        _("AffMar number"), max_length=100, null=True, blank=True +    ) +    drassm_number = models.CharField( +        _("DRASSM number"), max_length=100, null=True, blank=True +    )      documents = models.ManyToManyField( -        Document, related_name="sites", verbose_name=_("Documents"), -        blank=True) +        Document, related_name="sites", verbose_name=_("Documents"), blank=True +    )      main_image = models.ForeignKey( -        Document, related_name='main_image_sites', +        Document, +        related_name="main_image_sites",          on_delete=models.SET_NULL, -        verbose_name=_("Main image"), blank=True, null=True) +        verbose_name=_("Main image"), +        blank=True, +        null=True, +    )      cached_label = models.TextField( -        _("Cached name"), blank=True, default="", db_index=True, -        help_text=_("Generated automatically - do not edit") +        _("Cached name"), +        blank=True, +        default="", +        db_index=True, +        help_text=_("Generated automatically - do not edit"),      )      cached_towns_label = models.TextField( -        _("Cached town label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +        _("Cached town label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      ) -    cached_periods =  models.TextField( -        _("Cached periods label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +    cached_periods = models.TextField( +        _("Cached periods label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      ) -    cached_remains =  models.TextField( -        _("Cached remains label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +    cached_remains = models.TextField( +        _("Cached remains label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      )      history = HistoricalRecords(bases=[HistoryModel]) @@ -378,23 +440,18 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          verbose_name = _("Archaeological site")          verbose_name_plural = _("Archaeological sites")          permissions = ( -            ("view_archaeologicalsite", -             "Can view all Archaeological sites"), -            ("view_own_archaeologicalsite", -             "Can view own Archaeological site"), -            ("add_own_archaeologicalsite", -             "Can add own Archaeological site"), -            ("change_own_archaeologicalsite", -             "Can change own Archaeological site"), -            ("delete_own_archaeologicalsite", -             "Can delete own Archaeological site"), +            ("view_archaeologicalsite", "Can view all Archaeological sites"), +            ("view_own_archaeologicalsite", "Can view own Archaeological site"), +            ("add_own_archaeologicalsite", "Can add own Archaeological site"), +            ("change_own_archaeologicalsite", "Can change own Archaeological site"), +            ("delete_own_archaeologicalsite", "Can delete own Archaeological site"),          )          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      def __str__(self): -        return self.cached_label or '' +        return self.cached_label or ""      @property      def short_class_name(self): @@ -408,15 +465,17 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte      def public_representation(self):          dct = super(ArchaeologicalSite, self).public_representation() -        dct.update({ -            "reference": self.reference, -            "name": self.name, -            "periods": [str(p) for p in self.periods.all()], -            "remains": [str(r) for r in self.remains.all()], -            "towns": [t.label_with_areas for t in self.towns.all()], -            "comment": self.comment, -            "locality": self.locality_ngi or self.locality_cadastral, -        }) +        dct.update( +            { +                "reference": self.reference, +                "name": self.name, +                "periods": [str(p) for p in self.periods.all()], +                "remains": [str(r) for r in self.remains.all()], +                "towns": [t.label_with_areas for t in self.towns.all()], +                "comment": self.comment, +                "locality": self.locality_ngi or self.locality_cadastral, +            } +        )          profile = get_current_profile()          if profile.underwater:              dct["shipwreck-name"] = self.shipwreck_name @@ -427,8 +486,10 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte      @property      def finds(self):          from archaeological_finds.models import Find +          return Find.objects.filter( -            base_finds__context_record__archaeological_site__pk=self.pk) +            base_finds__context_record__archaeological_site__pk=self.pk +        )      def get_extra_actions(self, request):          """ @@ -438,11 +499,17 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          actions = super(ArchaeologicalSite, self).get_extra_actions(request)          # is_locked = self.is_locked(request.user) -        can_edit_site = self.can_do(request, 'change_archaeologicalsite') +        can_edit_site = self.can_do(request, "change_archaeologicalsite")          if can_edit_site:              actions += [ -                (reverse("site-qa-duplicate", args=[self.pk]), -                 _("Duplicate"), "fa fa-clone", "", "", True), +                ( +                    reverse("site-qa-duplicate", args=[self.pk]), +                    _("Duplicate"), +                    "fa fa-clone", +                    "", +                    "", +                    True, +                ),              ]          return actions @@ -451,13 +518,12 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          profile = ishtaruser.current_profile          town_ids = []          if profile: -            town_ids = [town['pk'] -                        for town in profile.query_towns.values('pk').all()] +            town_ids = [town["pk"] for town in profile.query_towns.values("pk").all()]          query_owns = [              { -                'collaborators__pk': ishtaruser.person.pk, -                'history_creator': ishtaruser.user_ptr, -                'towns__pk__in': town_ids, +                "collaborators__pk": ishtaruser.person.pk, +                "history_creator": ishtaruser.user_ptr, +                "towns__pk__in": town_ids,              }          ]          return query_owns @@ -465,55 +531,63 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte      @classmethod      def get_query_owns(cls, ishtaruser):          from archaeological_warehouse.models import Warehouse -        q = cls._construct_query_own( -            'operations__context_record__base_finds__find__container__responsible__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'operations__context_record__base_finds__find__basket__', -            [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}] -        ) | cls._construct_query_own( -            'operations__context_record__base_finds__find__container__location__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'top_operations__context_record__base_finds__find__container__responsible__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'top_operations__context_record__base_finds__find__container__location__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'operations__', Operation._get_query_owns_dicts(ishtaruser, -                                                            no_rel=True) -        ) | cls._construct_query_own( -            'top_operations__', Operation._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            '', cls._get_query_owns_dicts(ishtaruser) + +        q = ( +            cls._construct_query_own( +                "operations__context_record__base_finds__find__container__responsible__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "operations__context_record__base_finds__find__basket__", +                [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}], +            ) +            | cls._construct_query_own( +                "operations__context_record__base_finds__find__container__location__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "top_operations__context_record__base_finds__find__container__responsible__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "top_operations__context_record__base_finds__find__container__location__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "operations__", Operation._get_query_owns_dicts(ishtaruser, no_rel=True) +            ) +            | cls._construct_query_own( +                "top_operations__", Operation._get_query_owns_dicts(ishtaruser) +            ) +            | cls._construct_query_own("", cls._get_query_owns_dicts(ishtaruser))          )          return q      @classmethod -    def get_owns(cls, user, menu_filtr=None, limit=None, values=None, -                 get_short_menu_class=None): +    def get_owns( +        cls, user, menu_filtr=None, limit=None, values=None, get_short_menu_class=None +    ):          replace_query = None -        if menu_filtr and 'operation' in menu_filtr: -            replace_query = Q(operations=menu_filtr['operation']) +        if menu_filtr and "operation" in menu_filtr: +            replace_query = Q(operations=menu_filtr["operation"])          owns = super(ArchaeologicalSite, cls).get_owns( -            user, replace_query=replace_query, -            limit=limit, values=values, -            get_short_menu_class=get_short_menu_class) +            user, +            replace_query=replace_query, +            limit=limit, +            values=values, +            get_short_menu_class=get_short_menu_class, +        )          return cls._return_get_owns(owns, values, get_short_menu_class)      def _generate_cached_label(self):          name = self.reference          if self.name:              name += " %s %s" % (settings.JOINT, self.name) -        keys = [('towns', " - {}"), ('remains', " - {}"), -                ('periods', " [{}]")] +        keys = [("towns", " - {}"), ("remains", " - {}"), ("periods", " [{}]")]          for k, lbl in keys:              if getattr(self, k).count(): -                name += lbl.format(", ".join([ -                    str(v) for v in getattr(self, k).all() -                ])) +                name += lbl.format(", ".join([str(v) for v in getattr(self, k).all()]))          return name      def _generate_cached_towns_label(self): @@ -526,7 +600,7 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          return " & ".join([str(period) for period in self.periods.all()]) or "-"      def natural_key(self): -        return (self.reference, ) +        return (self.reference,)      @property      def external_id(self): @@ -539,15 +613,17 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte          return " & ".join(self.towns_codes())      def get_town_centroid(self): -        q = self.towns.filter(center__isnull=False).annotate( -                centroid=Centroid(Union('center'))).all() +        q = ( +            self.towns.filter(center__isnull=False) +            .annotate(centroid=Centroid(Union("center"))) +            .all() +        )          if not q.count():              return          return q.all()[0].centroid, self._meta.verbose_name      def get_town_polygons(self): -        q = self.towns.filter(limit__isnull=False).annotate( -            poly=Union('limit')).all() +        q = self.towns.filter(limit__isnull=False).annotate(poly=Union("limit")).all()          if not q.count():              return          return q.all()[0].poly, self._meta.verbose_name @@ -566,39 +642,32 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, CompleteIdentifierIte              if not create:                  return              operation_type, created = OperationType.objects.get_or_create( -                txt_idx='unknown', -                defaults={'label': _("Unknown"), 'available': True, -                          'order': 999}) -            name = str( -                _("Virtual operation of site: {}") -            ).format(self.reference) +                txt_idx="unknown", +                defaults={"label": _("Unknown"), "available": True, "order": 999}, +            ) +            name = str(_("Virtual operation of site: {}")).format(self.reference)              if self.towns.count(): -                name += ' - ' + ", ".join( -                    [town.name for town in self.towns.all()]) +                name += " - " + ", ".join([town.name for town in self.towns.all()])              operation = Operation.objects.create( -                operation_type=operation_type, -                common_name=name, -                virtual_operation=True +                operation_type=operation_type, common_name=name, virtual_operation=True              )              operation.top_sites.add(self)          top_operation = self.top_operations.all()[0]          current_operations = dict( -            [(ope.pk, ope) -             for ope in self.operations.exclude( -                pk=top_operation.pk -            ).all() -             ] +            [ +                (ope.pk, ope) +                for ope in self.operations.exclude(pk=top_operation.pk).all() +            ]          )          q = RecordRelations.objects.filter( -            left_record=top_operation, -            relation_type__txt_idx='has_got' +            left_record=top_operation, relation_type__txt_idx="has_got"          )          for relation in q.all():              if relation.right_record.pk not in current_operations:                  relation.delete()              else:                  current_operations.pop(relation.right_record.pk) -        rel_type = RelationType.get_cache('has_got') +        rel_type = RelationType.get_cache("has_got")          for missing, value in current_operations.items():              RecordRelations.objects.create(                  left_record=top_operation, @@ -614,45 +683,51 @@ def site_post_save(sender, **kwargs):  post_save.connect(site_post_save, sender=ArchaeologicalSite) -m2m_changed.connect(document_attached_changed, -                    sender=ArchaeologicalSite.documents.through) +m2m_changed.connect( +    document_attached_changed, sender=ArchaeologicalSite.documents.through +)  for attr in ArchaeologicalSite.HISTORICAL_M2M: -    m2m_changed.connect(m2m_historization_changed, -                        sender=getattr(ArchaeologicalSite, attr).through) +    m2m_changed.connect( +        m2m_historization_changed, sender=getattr(ArchaeologicalSite, attr).through +    )  def get_values_town_related(item, prefix, values, filtr=None): -    if not filtr or prefix + 'parcellist' in filtr: -        values[prefix + 'parcellist'] = item.render_parcels() -    if not filtr or prefix + 'towns_count' in filtr: -        values[prefix + 'towns_count'] = str(item.towns.count()) -    get_towns = not filtr or prefix + 'towns' in filtr -    get_dpt = not filtr or prefix + 'departments' in filtr -    get_dpt_nb = not filtr or prefix + 'departments_number' in filtr +    if not filtr or prefix + "parcellist" in filtr: +        values[prefix + "parcellist"] = item.render_parcels() +    if not filtr or prefix + "towns_count" in filtr: +        values[prefix + "towns_count"] = str(item.towns.count()) +    get_towns = not filtr or prefix + "towns" in filtr +    get_dpt = not filtr or prefix + "departments" in filtr +    get_dpt_nb = not filtr or prefix + "departments_number" in filtr      if not get_towns and not get_dpt and not get_dpt_nb:          return values      if get_towns: -        values[prefix + 'towns'] = '' +        values[prefix + "towns"] = ""      if get_dpt: -        values[prefix + 'departments'] = '' +        values[prefix + "departments"] = ""      if get_dpt_nb: -        values[prefix + 'departments_number'] = '' +        values[prefix + "departments_number"] = ""      if item.towns.count():          if get_towns: -            values[prefix + 'towns'] = ", ".join([ -               town.name for town in item.towns.all().order_by('name')]) -        if settings.COUNTRY == 'fr' and (get_dpt_nb or get_dpt_nb): -            dpts_num = set( -                [town.numero_insee[:2] for town in item.towns.all()]) +            values[prefix + "towns"] = ", ".join( +                [town.name for town in item.towns.all().order_by("name")] +            ) +        if settings.COUNTRY == "fr" and (get_dpt_nb or get_dpt_nb): +            dpts_num = set([town.numero_insee[:2] for town in item.towns.all()])              if get_dpt_nb: -                values[prefix + 'departments_number'] = ", ".join( -                    list(sorted(dpts_num))) +                values[prefix + "departments_number"] = ", ".join( +                    list(sorted(dpts_num)) +                )              if get_dpt: -                values[prefix + 'departments'] = ", ".join( -                    [Department.objects.get(number=dpt).label -                     for dpt in sorted(dpts_num) if Department.objects.filter( -                        number=dpt).count()]) +                values[prefix + "departments"] = ", ".join( +                    [ +                        Department.objects.get(number=dpt).label +                        for dpt in sorted(dpts_num) +                        if Department.objects.filter(number=dpt).count() +                    ] +                )      return values @@ -663,8 +738,7 @@ class ClosedItem(object):          in_history = False          date = self.end_date          # last action is closing? -        for idx, item in enumerate( -                self.history.order_by('-history_date').all()): +        for idx, item in enumerate(self.history.order_by("-history_date").all()):              if not idx:                  # last action                  continue @@ -681,123 +755,143 @@ class ClosedItem(object):              q = IshtarUser.objects.filter(pk=self.history_modifier_id)              if q.count():                  user = q.all()[0] -        return {'date': date, 'user': user} +        return {"date": date, "user": user}  class ParcelItem:      def clean_parcel_duplicates(self):          parcels = {} -        for p in self.parcels.order_by('pk').all(): +        for p in self.parcels.order_by("pk").all():              if p.associated_file:                  continue -            key = (p.section, p.parcel_number, p.year, p.town.pk, -                   p.public_domain) +            key = (p.section, p.parcel_number, p.year, p.town.pk, p.public_domain)              if key in parcels:                  parcels[key].merge(p)              else:                  parcels[key] = p -class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, -                CompleteIdentifierItem, GeoItem, OwnPerms, ValueGetter, -                MainItem, DashboardFormItem, RelationItem, ParcelItem): -    SLUG = 'operation' +class Operation( +    ClosedItem, +    DocumentItem, +    BaseHistorizedItem, +    CompleteIdentifierItem, +    GeoItem, +    OwnPerms, +    ValueGetter, +    MainItem, +    DashboardFormItem, +    RelationItem, +    ParcelItem, +): +    SLUG = "operation"      APP = "archaeological-operations"      MODEL = "operation" -    SHOW_URL = 'show-operation' -    DELETE_URL = 'delete-operation' -    TABLE_COLS = ['code_patriarche', 'year', 'cached_towns_label', -                  'common_name', 'operation_type__label', 'start_date', -                  'excavation_end_date', 'cached_remains'] +    SHOW_URL = "show-operation" +    DELETE_URL = "delete-operation" +    TABLE_COLS = [ +        "code_patriarche", +        "year", +        "cached_towns_label", +        "common_name", +        "operation_type__label", +        "start_date", +        "excavation_end_date", +        "cached_remains", +    ]      NEW_QUERY_ENGINE = True      # statistics -    STATISTIC_MODALITIES_OPTIONS = OrderedDict([ -        ("operation_type__label",  _("Operation type")), -        ('year', _("Year")), -        ("towns__areas__label", _("Area")), -        ("towns__areas__parent__label", _("Extended area")), -        ("remains__label", _("Remains")), -        ("periods__label", _("Periods")), -        ("record_quality_type__label", _("Record quality")), -        ("documentation_received", _("Documentation received")), -        ("finds_received", _("Finds received")), -        ("documents__source_type__label", _("Associated document type")), -    ]) -    STATISTIC_MODALITIES = [ -        key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()] +    STATISTIC_MODALITIES_OPTIONS = OrderedDict( +        [ +            ("operation_type__label", _("Operation type")), +            ("year", _("Year")), +            ("towns__areas__label", _("Area")), +            ("towns__areas__parent__label", _("Extended area")), +            ("remains__label", _("Remains")), +            ("periods__label", _("Periods")), +            ("record_quality_type__label", _("Record quality")), +            ("documentation_received", _("Documentation received")), +            ("finds_received", _("Finds received")), +            ("documents__source_type__label", _("Associated document type")), +        ] +    ) +    STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]      # search parameters -    BOOL_FIELDS = ['end_date__isnull', 'virtual_operation', -                   'documentation_received', 'finds_received'] -    MANY_COUNTED_FIELDS = ['context_record__base_finds'] +    BOOL_FIELDS = [ +        "end_date__isnull", +        "virtual_operation", +        "documentation_received", +        "finds_received", +    ] +    MANY_COUNTED_FIELDS = ["context_record__base_finds"]      REVERSED_BOOL_FIELDS = [ -        'documents__image__isnull', -        'documents__associated_file__isnull', -        'documents__associated_url__isnull', +        "documents__image__isnull", +        "documents__associated_file__isnull", +        "documents__associated_url__isnull",      ]      DATED_FIELDS = [ -        'start_date__lte', 'start_date__gte', 'excavation_end_date__lte', -        'excavation_end_date__gte', 'documentation_deadline__lte', -        'documentation_deadline__gte', 'finds_deadline__lte', -        'finds_deadline__gte'] +        "start_date__lte", +        "start_date__gte", +        "excavation_end_date__lte", +        "excavation_end_date__gte", +        "documentation_deadline__lte", +        "documentation_deadline__gte", +        "finds_deadline__lte", +        "finds_deadline__gte", +    ]      EXTRA_REQUEST_KEYS = { -        'operation_type__label': 'operation_type__label', -        'common_name': 'common_name__icontains', -        'cached_label': 'cached_label__icontains', -        'comment': 'comment__icontains', -        'scientific_documentation_comment': -        'scientific_documentation_comment__icontains', -        'abstract': 'abstract__icontains', -        'end_date': 'end_date__isnull', -        'start_before': 'start_date__lte', -        'start_after': 'start_date__gte', -        'end_before': 'excavation_end_date__lte', -        'end_after': 'excavation_end_date__gte', -        'towns__numero_insee__startswith': -        'towns__numero_insee__startswith', -        'parcel': 'parcels__cached_label__iexact', -        'history_creator': -        'history_creator__ishtaruser__person__pk', -        'history_modifier': -        'history_modifier__ishtaruser__person__pk', -        'documentation_deadline_before': 'documentation_deadline__lte', -        'documentation_deadline_after': 'documentation_deadline__gte', -        'finds_deadline_before': 'finds_deadline__lte', -        'finds_deadline_after': 'finds_deadline__gte', -        'related_treatment': -        'context_record__base_finds__find__upstream_treatment__id', -        'towns_label': 'towns', -        'scientist__pk': 'scientist__pk',  # dynamic_table_documents -        'in_charge__pk': 'in_charge__pk',  # dynamic_table_documents -        'collaborators__pk': 'collaborators__pk',  # dynamic_table_documents -        'cira_rapporteur__pk': 'cira_rapporteur__pk'  # dynamic_table_documents +        "operation_type__label": "operation_type__label", +        "common_name": "common_name__icontains", +        "cached_label": "cached_label__icontains", +        "comment": "comment__icontains", +        "scientific_documentation_comment": "scientific_documentation_comment__icontains", +        "abstract": "abstract__icontains", +        "end_date": "end_date__isnull", +        "start_before": "start_date__lte", +        "start_after": "start_date__gte", +        "end_before": "excavation_end_date__lte", +        "end_after": "excavation_end_date__gte", +        "towns__numero_insee__startswith": "towns__numero_insee__startswith", +        "parcel": "parcels__cached_label__iexact", +        "history_creator": "history_creator__ishtaruser__person__pk", +        "history_modifier": "history_modifier__ishtaruser__person__pk", +        "documentation_deadline_before": "documentation_deadline__lte", +        "documentation_deadline_after": "documentation_deadline__gte", +        "finds_deadline_before": "finds_deadline__lte", +        "finds_deadline_after": "finds_deadline__gte", +        "related_treatment": "context_record__base_finds__find__upstream_treatment__id", +        "towns_label": "towns", +        "scientist__pk": "scientist__pk",  # dynamic_table_documents +        "in_charge__pk": "in_charge__pk",  # dynamic_table_documents +        "collaborators__pk": "collaborators__pk",  # dynamic_table_documents +        "cira_rapporteur__pk": "cira_rapporteur__pk",  # dynamic_table_documents      }      COL_LABELS = { -        'code_patriarche': "Code patriarche", -        'associated_file_short_label': _("Associated file (label)"), -        'operator__name': _("Operator name"), -        'scientist__raw_name': _("Scientist (full name)"), -        'associated_file__external_id': _("Associated file (external ID)"), -        'scientist__title': _("Scientist (title)"), -        'scientist__surname': _("Scientist (surname)"), -        'scientist__name': _("Scientist (name)"), -        'scientist__attached_to__name': _("Scientist - Organization (name)"), -        'in_charge__title': _("In charge (title)"), -        'in_charge__surname': _("In charge (surname)"), -        'in_charge__name': _("In charge (name)"), -        'in_charge__attached_to__name': _("In charge - Organization (name)"), -        'cira_rapporteur__surname': "Rapporteur CTRA/CIRA (prénom)", -        'cira_rapporteur__name': "Rapporteur CTRA/CIRA (nom)", -        'cira_rapporteur__attached_to__name': "Rapporteur CTRA/CIRA - " -                                              "Organisation (nom)", -        'archaeological_sites__reference': -        _("Archaeological sites (reference)"), -        'towns_label': _("Towns"), -        'operation_type__label': _("Operation type"), -        'cached_towns_label': _("Towns"), -        'cached_periods': _("Periods"), -        'cached_remains': _("Remains"), +        "code_patriarche": "Code patriarche", +        "associated_file_short_label": _("Associated file (label)"), +        "operator__name": _("Operator name"), +        "scientist__raw_name": _("Scientist (full name)"), +        "associated_file__external_id": _("Associated file (external ID)"), +        "scientist__title": _("Scientist (title)"), +        "scientist__surname": _("Scientist (surname)"), +        "scientist__name": _("Scientist (name)"), +        "scientist__attached_to__name": _("Scientist - Organization (name)"), +        "in_charge__title": _("In charge (title)"), +        "in_charge__surname": _("In charge (surname)"), +        "in_charge__name": _("In charge (name)"), +        "in_charge__attached_to__name": _("In charge - Organization (name)"), +        "cira_rapporteur__surname": "Rapporteur CTRA/CIRA (prénom)", +        "cira_rapporteur__name": "Rapporteur CTRA/CIRA (nom)", +        "cira_rapporteur__attached_to__name": "Rapporteur CTRA/CIRA - " +        "Organisation (nom)", +        "archaeological_sites__reference": _("Archaeological sites (reference)"), +        "towns_label": _("Towns"), +        "operation_type__label": _("Operation type"), +        "cached_towns_label": _("Towns"), +        "cached_periods": _("Periods"), +        "cached_remains": _("Remains"),      }      BASE_SEARCH_VECTORS = [          SearchVectorConfig("abstract", "local"), @@ -834,368 +928,427 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      PARENT_SEARCH_VECTORS = ["associated_file"]      PARENT_ONLY_SEARCH_VECTORS = ["archaeological_sites"]      ASSOCIATED = { -        "scientist": { -            ('person_types', PersonType): ( -                'head_scientist', -                'sra_agent' -            ) -        }, +        "scientist": {("person_types", PersonType): ("head_scientist", "sra_agent")},      } -    CACHED_LABELS = ['cached_label', 'cached_towns_label', 'cached_periods', -                     'cached_remains'] +    CACHED_LABELS = [ +        "cached_label", +        "cached_towns_label", +        "cached_periods", +        "cached_remains", +    ]      objects = UUIDModelManager()      # alternative names of fields for searches      ALT_NAMES = { -        'year': SearchAltName( -            pgettext_lazy("key for text search", "year"), -            'year' +        "year": SearchAltName(pgettext_lazy("key for text search", "year"), "year"), +        "operation_code": SearchAltName( +            pgettext_lazy("key for text search", "operation-code"), "operation_code"          ), -        'operation_code': SearchAltName( -            pgettext_lazy("key for text search", "operation-code"), -            'operation_code' -        ), -        'code_patriarche': SearchAltName( +        "code_patriarche": SearchAltName(              pgettext_lazy("key for text search", "patriarche"), -            'code_patriarche__iexact' +            "code_patriarche__iexact",          ), -        'towns': SearchAltName( -            pgettext_lazy("key for text search", "town"), -            'towns__cached_label__iexact' +        "towns": SearchAltName( +            pgettext_lazy("key for text search", "town"), "towns__cached_label__iexact"          ), -        'towns__areas': SearchAltName( -            pgettext_lazy("key for text search", "area"), -            'towns__areas__label__iexact' +        "towns__areas": SearchAltName( +            pgettext_lazy("key for text search", "area"), "towns__areas__label__iexact"          ), -        'parcel': SearchAltName( +        "parcel": SearchAltName(              pgettext_lazy("key for text search", "parcel"), -            'parcels__cached_label__iexact' +            "parcels__cached_label__iexact",          ), -        'towns__numero_insee__startswith': SearchAltName( +        "towns__numero_insee__startswith": SearchAltName(              pgettext_lazy("key for text search", "department"), -            'towns__numero_insee__startswith' +            "towns__numero_insee__startswith",          ), -        'common_name': SearchAltName( -            pgettext_lazy("key for text search", "name"), -            'common_name__iexact' +        "common_name": SearchAltName( +            pgettext_lazy("key for text search", "name"), "common_name__iexact"          ), -        'address': SearchAltName( -            pgettext_lazy("key for text search", "address"), -            'address__iexact' +        "address": SearchAltName( +            pgettext_lazy("key for text search", "address"), "address__iexact"          ), -        'operation_type': SearchAltName( +        "operation_type": SearchAltName(              pgettext_lazy("key for text search", "type"), -            'operation_type__label__iexact' +            "operation_type__label__iexact",          ), -        'end_date': SearchAltName( -            pgettext_lazy("key for text search", "is-open"), -            'end_date__isnull' +        "end_date": SearchAltName( +            pgettext_lazy("key for text search", "is-open"), "end_date__isnull"          ), -        'in_charge': SearchAltName( +        "in_charge": SearchAltName(              pgettext_lazy("key for text search", "in-charge"), -            'in_charge__cached_label__iexact' +            "in_charge__cached_label__iexact",          ), -        'scientist': SearchAltName( +        "scientist": SearchAltName(              pgettext_lazy("key for text search", "scientist"), -            'scientist__cached_label__iexact' +            "scientist__cached_label__iexact",          ), -        'operator': SearchAltName( +        "operator": SearchAltName(              pgettext_lazy("key for text search", "operator"), -            'operator__cached_label__iexact' +            "operator__cached_label__iexact",          ), -        'remains': SearchAltName( -            pgettext_lazy("key for text search", "remain"), -            'remains__label__iexact' +        "remains": SearchAltName( +            pgettext_lazy("key for text search", "remain"), "remains__label__iexact"          ), -        'periods': SearchAltName( -            pgettext_lazy("key for text search", "period"), -            'periods__label__iexact' +        "periods": SearchAltName( +            pgettext_lazy("key for text search", "period"), "periods__label__iexact"          ), -        'start_before': SearchAltName( -            pgettext_lazy("key for text search", "start-before"), -            'start_date__lte' +        "start_before": SearchAltName( +            pgettext_lazy("key for text search", "start-before"), "start_date__lte"          ), -        'start_after': SearchAltName( -            pgettext_lazy("key for text search", "start-after"), -            'start_date__gte' +        "start_after": SearchAltName( +            pgettext_lazy("key for text search", "start-after"), "start_date__gte"          ), -        'end_before': SearchAltName( +        "end_before": SearchAltName(              pgettext_lazy("key for text search", "end-before"), -            'excavation_end_date__lte' +            "excavation_end_date__lte",          ), -        'end_after': SearchAltName( +        "end_after": SearchAltName(              pgettext_lazy("key for text search", "end-after"), -            'excavation_end_date__gte' +            "excavation_end_date__gte",          ), -        'relation_types': SearchAltName( -            pgettext_lazy("key for text search", "relation-types"), -            'relation_types' +        "relation_types": SearchAltName( +            pgettext_lazy("key for text search", "relation-types"), "relation_types"          ), -        'comment': SearchAltName( -            pgettext_lazy("key for text search", "comment"), -            'comment__iexact' +        "comment": SearchAltName( +            pgettext_lazy("key for text search", "comment"), "comment__iexact"          ), -        'abstract': SearchAltName( -            pgettext_lazy("key for text search", "abstract"), -            'abstract__iexact' +        "abstract": SearchAltName( +            pgettext_lazy("key for text search", "abstract"), "abstract__iexact"          ), -        'scientific_documentation_comment': SearchAltName( -            pgettext_lazy("key for text search", -                          "scientific-documentation-comment"), -            'scientific_documentation_comment__iexact' +        "scientific_documentation_comment": SearchAltName( +            pgettext_lazy("key for text search", "scientific-documentation-comment"), +            "scientific_documentation_comment__iexact",          ), -        'record_quality_type': SearchAltName( +        "record_quality_type": SearchAltName(              pgettext_lazy("key for text search", "record-quality"), -            'record_quality_type__label__iexact' +            "record_quality_type__label__iexact",          ), -        'report_processing': SearchAltName( -            pgettext_lazy("key for text search", -                          "report-processing"), -            'report_processing__label__iexact' +        "report_processing": SearchAltName( +            pgettext_lazy("key for text search", "report-processing"), +            "report_processing__label__iexact",          ), -        'virtual_operation': SearchAltName( -            pgettext_lazy("key for text search", -                          "virtual-operation"), -            'virtual_operation' +        "virtual_operation": SearchAltName( +            pgettext_lazy("key for text search", "virtual-operation"), +            "virtual_operation",          ), -        'archaeological_sites': SearchAltName( -            pgettext_lazy("key for text search", -                          "site"), -            'archaeological_sites__cached_label__icontains' +        "archaeological_sites": SearchAltName( +            pgettext_lazy("key for text search", "site"), +            "archaeological_sites__cached_label__icontains",          ), -        'documentation_received': SearchAltName( +        "documentation_received": SearchAltName(              pgettext_lazy("key for text search", "documentation-received"), -            'documentation_received' +            "documentation_received",          ), -        'documentation_deadline_before': SearchAltName( +        "documentation_deadline_before": SearchAltName(              pgettext_lazy("key for text search", "documentation-deadline-before"), -            'documentation_deadline__lte' +            "documentation_deadline__lte",          ), -        'documentation_deadline_after': SearchAltName( +        "documentation_deadline_after": SearchAltName(              pgettext_lazy("key for text search", "documentation-deadline-after"), -            'documentation_deadline__gte' +            "documentation_deadline__gte",          ), -        'finds_received': SearchAltName( -            pgettext_lazy("key for text search", "finds-received"), -            'finds_received' +        "finds_received": SearchAltName( +            pgettext_lazy("key for text search", "finds-received"), "finds_received"          ), -        'has_finds': SearchAltName( +        "has_finds": SearchAltName(              pgettext_lazy("key for text search", "has-finds"), -            'context_record__base_finds' +            "context_record__base_finds",          ), -        'finds_deadline_before': SearchAltName( +        "finds_deadline_before": SearchAltName(              pgettext_lazy("key for text search", "finds-deadline-before"), -            'finds_deadline__lte' +            "finds_deadline__lte",          ), -        'finds_deadline_after': SearchAltName( +        "finds_deadline_after": SearchAltName(              pgettext_lazy("key for text search", "finds-deadline-after"), -            'finds_deadline__gte' +            "finds_deadline__gte",          ), -        'drassm_code': SearchAltName( -            pgettext_lazy("key for text search", "code-drassm"), -            'drassm_code__iexact' +        "drassm_code": SearchAltName( +            pgettext_lazy("key for text search", "code-drassm"), "drassm_code__iexact"          ),      }      ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)      ALT_NAMES.update(DocumentItem.ALT_NAMES)      QA_EDIT = QuickAction( -        url="operation-qa-bulk-update", icon_class="fa fa-pencil", -        text=_("Bulk update"), target="many", -        rights=['change_operation', 'change_own_operation'] +        url="operation-qa-bulk-update", +        icon_class="fa fa-pencil", +        text=_("Bulk update"), +        target="many", +        rights=["change_operation", "change_own_operation"],      )      QA_LOCK = QuickAction( -        url="operation-qa-lock", icon_class="fa fa-lock", -        text=_("Lock/Unlock"), target="many", -        rights=['change_operation', 'change_own_operation'] +        url="operation-qa-lock", +        icon_class="fa fa-lock", +        text=_("Lock/Unlock"), +        target="many", +        rights=["change_operation", "change_own_operation"],      )      QUICK_ACTIONS = [ -        QA_EDIT, QA_LOCK, +        QA_EDIT, +        QA_LOCK,          QuickAction( -            url="operation-qa-duplicate", icon_class="fa fa-clone", -            text=_("Duplicate"), target="one", -            rights=['change_operation', 'change_own_operation']), +            url="operation-qa-duplicate", +            icon_class="fa fa-clone", +            text=_("Duplicate"), +            target="one", +            rights=["change_operation", "change_own_operation"], +        ),      ]      UP_MODEL_QUERY = { -        "site": (pgettext_lazy("key for text search", "site"), -                 'cached_label'), -        "file": (pgettext_lazy("key for text search", "file"), -                 'cached_label'), +        "site": (pgettext_lazy("key for text search", "site"), "cached_label"), +        "file": (pgettext_lazy("key for text search", "file"), "cached_label"),      }      RELATIVE_SESSION_NAMES = [ -        ('file', 'associated_file__pk'), -        ('site', 'archaeological_sites__pk'), +        ("file", "associated_file__pk"), +        ("site", "archaeological_sites__pk"),      ]      POST_PROCESS_REQUEST = { -        'towns__numero_insee__startswith': '_get_department_code', +        "towns__numero_insee__startswith": "_get_department_code",      }      DOWN_MODEL_UPDATE = ["context_record"]      HISTORICAL_M2M = [ -        'remains', 'towns', 'periods', +        "remains", +        "towns", +        "periods",      ]      # fields definition      uuid = models.UUIDField(default=uuid.uuid4) -    creation_date = models.DateField(_("Creation date"), -                                     default=datetime.date.today) +    creation_date = models.DateField(_("Creation date"), default=datetime.date.today)      end_date = models.DateField(_("Closing date"), null=True, blank=True)      start_date = models.DateField(_("Start date"), null=True, blank=True)      excavation_end_date = models.DateField( -        _("Excavation end date"), null=True, blank=True) -    report_delivery_date = models.DateField(_("Report delivery date"), -                                            null=True, blank=True) +        _("Excavation end date"), null=True, blank=True +    ) +    report_delivery_date = models.DateField( +        _("Report delivery date"), null=True, blank=True +    )      scientist = models.ForeignKey( -        Person, blank=True, null=True, verbose_name=_("In charge scientist"), +        Person, +        blank=True, +        null=True, +        verbose_name=_("In charge scientist"),          on_delete=models.SET_NULL, -        related_name='operation_scientist_responsability') +        related_name="operation_scientist_responsability", +    )      operator = models.ForeignKey( -        Organization, blank=True, null=True, related_name='operator', -        verbose_name=_("Operator"), on_delete=models.SET_NULL) -    in_charge = models.ForeignKey(Person, blank=True, null=True, -                                  verbose_name=_("In charge"), -                                  on_delete=models.SET_NULL, -                                  related_name='operation_responsability') +        Organization, +        blank=True, +        null=True, +        related_name="operator", +        verbose_name=_("Operator"), +        on_delete=models.SET_NULL, +    ) +    in_charge = models.ForeignKey( +        Person, +        blank=True, +        null=True, +        verbose_name=_("In charge"), +        on_delete=models.SET_NULL, +        related_name="operation_responsability", +    )      collaborators = models.ManyToManyField( -        Person, blank=True, verbose_name=_("Collaborators"), -        related_name='operation_collaborator' +        Person, +        blank=True, +        verbose_name=_("Collaborators"), +        related_name="operation_collaborator",      )      year = models.IntegerField(_("Year"), null=True, blank=True) -    operation_code = models.IntegerField(_("Numeric reference"), null=True, -                                         blank=True) +    operation_code = models.IntegerField(_("Numeric reference"), null=True, blank=True)      associated_file = models.ForeignKey( -        'archaeological_files.File', -        related_name='operations', verbose_name=_("File"), +        "archaeological_files.File", +        related_name="operations", +        verbose_name=_("File"),          on_delete=models.SET_NULL, -        blank=True, null=True) -    operation_type = models.ForeignKey(OperationType, related_name='+', -                                       verbose_name=_("Operation type")) +        blank=True, +        null=True, +    ) +    operation_type = models.ForeignKey( +        OperationType, related_name="+", verbose_name=_("Operation type") +    )      surface = models.IntegerField(_("Surface (m2)"), blank=True, null=True) -    remains = models.ManyToManyField("RemainType", verbose_name=_('Remains'), -                                     blank=True) -    towns = models.ManyToManyField(Town, verbose_name=_("Towns"), -                                   related_name='operations') -    cost = models.IntegerField(_("Cost (euros)"), -                               blank=True, null=True)  # preventive -    periods = models.ManyToManyField(Period, verbose_name=_("Periods"), -                                     blank=True) +    remains = models.ManyToManyField( +        "RemainType", verbose_name=_("Remains"), blank=True +    ) +    towns = models.ManyToManyField( +        Town, verbose_name=_("Towns"), related_name="operations" +    ) +    cost = models.IntegerField(_("Cost (euros)"), blank=True, null=True)  # preventive +    periods = models.ManyToManyField(Period, verbose_name=_("Periods"), blank=True)      # preventive -    scheduled_man_days = models.IntegerField(_("Scheduled man-days"), -                                             blank=True, null=True) +    scheduled_man_days = models.IntegerField( +        _("Scheduled man-days"), blank=True, null=True +    )      # preventive -    optional_man_days = models.IntegerField(_("Optional man-days"), -                                            blank=True, null=True) +    optional_man_days = models.IntegerField( +        _("Optional man-days"), blank=True, null=True +    )      # preventive -    effective_man_days = models.IntegerField(_("Effective man-days"), -                                             blank=True, null=True) +    effective_man_days = models.IntegerField( +        _("Effective man-days"), blank=True, null=True +    )      report_processing = models.ForeignKey( -        ReportState, verbose_name=_("Report processing"), +        ReportState, +        verbose_name=_("Report processing"),          on_delete=models.SET_NULL, -        blank=True, null=True) -    old_code = models.CharField(_("Old code"), max_length=200, null=True, -                                blank=True) +        blank=True, +        null=True, +    ) +    old_code = models.CharField(_("Old code"), max_length=200, null=True, blank=True)      ## fr      code_patriarche = models.TextField( -        "Code PATRIARCHE", blank=True, default="", unique=True) +        "Code PATRIARCHE", blank=True, default="", unique=True +    )      # preventive -    fnap_financing = models.FloatField("Financement FNAP (%)", -                                       blank=True, null=True) +    fnap_financing = models.FloatField("Financement FNAP (%)", blank=True, null=True)      # preventive -    fnap_cost = models.IntegerField("Financement FNAP (€)", -                                    blank=True, null=True) +    fnap_cost = models.IntegerField("Financement FNAP (€)", blank=True, null=True)      # preventive diag      zoning_prescription = models.NullBooleanField( -        _("Prescription on zoning"), blank=True, null=True) +        _("Prescription on zoning"), blank=True, null=True +    )      # preventive diag      large_area_prescription = models.NullBooleanField( -        _("Prescription on large area"), blank=True, null=True) +        _("Prescription on large area"), blank=True, null=True +    )      geoarchaeological_context_prescription = models.NullBooleanField( -        _("Prescription on geoarchaeological context"), blank=True, -        null=True)  # preventive diag +        _("Prescription on geoarchaeological context"), blank=True, null=True +    )  # preventive diag      cira_rapporteur = models.ForeignKey( -        Person, related_name='cira_rapporteur', null=True, blank=True, -        on_delete=models.SET_NULL, verbose_name="Rapporteur CTRA/CIRA") +        Person, +        related_name="cira_rapporteur", +        null=True, +        blank=True, +        on_delete=models.SET_NULL, +        verbose_name="Rapporteur CTRA/CIRA", +    )      negative_result = models.NullBooleanField( -        "Résultat considéré comme négatif", blank=True, null=True) +        "Résultat considéré comme négatif", blank=True, null=True +    )      cira_date = models.DateField("Date avis CTRA/CIRA", null=True, blank=True) -    eas_number = models.CharField("Numéro de l'EA", max_length=20, -                                  null=True, blank=True) +    eas_number = models.CharField( +        "Numéro de l'EA", max_length=20, null=True, blank=True +    )      ## end fr      operator_reference = models.CharField( -        _("Operator reference"), max_length=20, null=True, blank=True) +        _("Operator reference"), max_length=20, null=True, blank=True +    )      common_name = models.TextField(_("Generic name"), blank=True, default="")      address = models.TextField(_("Address / Locality"), blank=True, default="")      comment = models.TextField(_("Comment"), blank=True, default="")      scientific_documentation_comment = models.TextField( -        _("Comment about scientific documentation"), blank=True, default="") +        _("Comment about scientific documentation"), blank=True, default="" +    )      documents = models.ManyToManyField( -        Document, related_name='operations', verbose_name=_("Documents"), -        blank=True) +        Document, related_name="operations", verbose_name=_("Documents"), blank=True +    )      main_image = models.ForeignKey( -        Document, related_name='main_image_operations', +        Document, +        related_name="main_image_operations",          on_delete=models.SET_NULL, -        verbose_name=_("Main image"), blank=True, null=True) +        verbose_name=_("Main image"), +        blank=True, +        null=True, +    )      cached_label = models.CharField( -        _("Cached name"), max_length=500, -        help_text=_( "Generated automatically - do not edit"), -        null=True, blank=True, db_index=True) +        _("Cached name"), +        max_length=500, +        help_text=_("Generated automatically - do not edit"), +        null=True, +        blank=True, +        db_index=True, +    )      archaeological_sites = models.ManyToManyField( -        ArchaeologicalSite, verbose_name=_("Archaeological sites"), -        blank=True, related_name='operations') +        ArchaeologicalSite, +        verbose_name=_("Archaeological sites"), +        blank=True, +        related_name="operations", +    )      top_sites = models.ManyToManyField(          ArchaeologicalSite,          verbose_name=_("Sites for which this operation is top operation"), -        related_name="top_operations", blank=True) +        related_name="top_operations", +        blank=True, +    )      virtual_operation = models.BooleanField(          _("Virtual operation"), -        default=False, help_text=_( +        default=False, +        help_text=_(              "If checked, it means that this operation have not been " -            "officialy registered.")) +            "officialy registered." +        ), +    )      record_quality_type = models.ForeignKey( -        RecordQualityType, verbose_name=_("Record quality"), +        RecordQualityType, +        verbose_name=_("Record quality"),          on_delete=models.SET_NULL, -        null=True, blank=True,) +        null=True, +        blank=True, +    )      abstract = models.TextField(_("Abstract"), blank=True, default="")      documentation_deadline = models.DateField( -        _("Deadline for submission of the documentation"), blank=True, -        null=True) +        _("Deadline for submission of the documentation"), blank=True, null=True +    )      documentation_received = models.NullBooleanField( -        _("Documentation received"), blank=True, null=True) +        _("Documentation received"), blank=True, null=True +    )      finds_deadline = models.DateField( -        _("Deadline for submission of the finds"), blank=True, null=True) -    finds_received = models.NullBooleanField( -        _("Finds received"), blank=True, null=True) +        _("Deadline for submission of the finds"), blank=True, null=True +    ) +    finds_received = models.NullBooleanField(_("Finds received"), blank=True, null=True)      # underwater -    drassm_code = models.CharField(_("DRASSM code"), max_length=100, -                                   null=True, blank=True) +    drassm_code = models.CharField( +        _("DRASSM code"), max_length=100, null=True, blank=True +    )      # judiciary      seizure_name = models.TextField(_("Seizure name"), blank=True, default="") -    official_report_number = models.TextField(_("Official report number"), -                                              blank=True, default="") +    official_report_number = models.TextField( +        _("Official report number"), blank=True, default="" +    )      protagonist = models.ForeignKey( -        Person, verbose_name=_("Name of the protagonist"), -        blank=True, null=True, related_name="operation_protagonist") +        Person, +        verbose_name=_("Name of the protagonist"), +        blank=True, +        null=True, +        related_name="operation_protagonist", +    )      applicant_authority = models.ForeignKey( -        Organization, verbose_name=_("Applicant authority"), -        blank=True, null=True, related_name="operation_applicant_authority") +        Organization, +        verbose_name=_("Applicant authority"), +        blank=True, +        null=True, +        related_name="operation_applicant_authority", +    )      minutes_writer = models.ForeignKey( -        Person, verbose_name=_("Writer of the minutes"), -        blank=True, null=True, related_name="minutes_writer") +        Person, +        verbose_name=_("Writer of the minutes"), +        blank=True, +        null=True, +        related_name="minutes_writer", +    )      cached_towns_label = models.TextField( -        _("Cached town label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +        _("Cached town label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      )      cached_periods = models.TextField( -        _("Cached periods label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +        _("Cached periods label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      )      cached_remains = models.TextField( -        _("Cached remains label"), blank=True, default="", -        help_text=_("Generated automatically - do not edit") +        _("Cached remains label"), +        blank=True, +        default="", +        help_text=_("Generated automatically - do not edit"),      )      history = HistoricalRecords(bases=[HistoryModel]) @@ -1211,25 +1364,29 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,              ("delete_own_operation", "Can delete own Operation"),              ("close_operation", "Can close Operation"),          ) -        ordering = ('cached_label',) +        ordering = ("cached_label",)          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      def natural_key(self): -        return (self.uuid, ) +        return (self.uuid,)      @classmethod -    def get_owns(cls, user, menu_filtr=None, limit=None, values=None, -                 get_short_menu_class=None): +    def get_owns( +        cls, user, menu_filtr=None, limit=None, values=None, get_short_menu_class=None +    ):          replace_query = None -        if menu_filtr and 'file' in menu_filtr: -            replace_query = Q(associated_file=menu_filtr['file']) +        if menu_filtr and "file" in menu_filtr: +            replace_query = Q(associated_file=menu_filtr["file"])          owns = super(Operation, cls).get_owns( -            user, replace_query=replace_query, -            limit=limit, values=values, -            get_short_menu_class=get_short_menu_class) +            user, +            replace_query=replace_query, +            limit=limit, +            values=values, +            get_short_menu_class=get_short_menu_class, +        )          return cls._return_get_owns(owns, values, get_short_menu_class)      def __str__(self): @@ -1245,48 +1402,53 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          Container = apps.get_model("archaeological_warehouse", "Container")          containers = []          q = Container.objects.filter( -            finds__base_finds__context_record__operation=self).distinct("index") +            finds__base_finds__context_record__operation=self +        ).distinct("index")          exclude += ["operation", "context_record"]          for c in q.order_by("index").all():              containers.append(c.get_values(filtr=filtr, exclude=exclude))          return containers -    def get_values(self, prefix='', no_values=False, filtr=None, **kwargs): +    def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):          values = super(Operation, self).get_values( -            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) +            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs +        )          values = get_values_town_related(self, prefix, values, filtr=filtr)          exclude = kwargs.get("exclude", [])          if prefix:              return values -        if (not filtr or 'context_records' in filtr) and \ -                "context_records" not in exclude: +        if ( +            not filtr or "context_records" in filtr +        ) and "context_records" not in exclude:              kwargs["no_base_finds"] = False -            values['context_records'] = [ -                cr.get_values(prefix=prefix, no_values=True, filtr=None, -                              **kwargs) +            values["context_records"] = [ +                cr.get_values(prefix=prefix, no_values=True, filtr=None, **kwargs)                  for cr in self.context_record.all()              ] -        if (not filtr or "containers" in filtr) \ -                and "context_records" not in exclude: +        if (not filtr or "containers" in filtr) and "context_records" not in exclude:              values["containers"] = self.get_containers_values(filtr, exclude)          return values      def public_representation(self):          dct = super(Operation, self).public_representation() -        year = self.year \ -            if self.year and self.year != settings.ISHTAR_DEFAULT_YEAR \ +        year = ( +            self.year +            if self.year and self.year != settings.ISHTAR_DEFAULT_YEAR              else None -        dct.update({ -            "year": year, -            "common-name": self.common_name, -            "operation-type": self.operation_type and str(self.operation_type), -            "remains": [str(r) for r in self.remains.all()], -            "periods": [str(p) for p in self.periods.all()], -            "excavation-start-date": self.start_date, -            "excavation-end-date": self.excavation_end_date, -            "address": self.address, -            "comment": self.comment, -        }) +        ) +        dct.update( +            { +                "year": year, +                "common-name": self.common_name, +                "operation-type": self.operation_type and str(self.operation_type), +                "remains": [str(r) for r in self.remains.all()], +                "periods": [str(p) for p in self.periods.all()], +                "excavation-start-date": self.start_date, +                "excavation-end-date": self.excavation_end_date, +                "address": self.address, +                "comment": self.comment, +            } +        )          return dct      @classmethod @@ -1308,7 +1470,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @property      def short_label(self): -        if settings.COUNTRY == 'fr': +        if settings.COUNTRY == "fr":              return self.reference          return str(self) @@ -1322,7 +1484,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @property      def show_url(self): -        return reverse('show-operation', args=[self.pk, '']) +        return reverse("show-operation", args=[self.pk, ""])      def towns_codes(self):          return [town.label_with_areas for town in self.towns.all()] @@ -1332,10 +1494,12 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      def has_finds(self):          from archaeological_finds.models import BaseFind +          return BaseFind.objects.filter(context_record__operation=self).count()      def finds(self):          from archaeological_finds.models import BaseFind +          return BaseFind.objects.filter(context_record__operation=self)      def get_reference(self, full=False): @@ -1349,8 +1513,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,              if ref:                  ref += " - "              ref += profile.default_operation_prefix -            ref += "-".join((str(self.year), -                              str(self.operation_code))) +            ref += "-".join((str(self.year), str(self.operation_code)))          return ref or "00"      @property @@ -1360,11 +1523,11 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          if isinstance(self.code_patriarche, int):              self.code_patriarche = str(self.code_patriarche)          profile = get_current_profile() -        if not profile.operation_region_code or \ -                not self.code_patriarche.startswith( -                    profile.operation_region_code): +        if not profile.operation_region_code or not self.code_patriarche.startswith( +            profile.operation_region_code +        ):              return self.code_patriarche -        return self.code_patriarche[len(profile.operation_region_code):] +        return self.code_patriarche[len(profile.operation_region_code) :]      @property      def reference(self): @@ -1408,15 +1571,15 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          return "{}/{}/{}".format(self.SLUG, self.year, self.reference)      def get_town_label(self): -        lbl = str(_('Intercommunal')) +        lbl = str(_("Intercommunal"))          if self.towns.count() == 1: -            lbl = self.towns.values('name').all()[0]['name'] +            lbl = self.towns.values("name").all()[0]["name"]          return lbl      def get_department(self):          if not self.towns.count(): -            return '00' -        return self.towns.values('numero_insee').all()[0]['numero_insee'][:2] +            return "00" +        return self.towns.values("numero_insee").all()[0]["numero_insee"][:2]      def grouped_parcels(self):          return Parcel.grouped_parcels(list(self.parcels.distinct().all())) @@ -1425,34 +1588,37 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          return Parcel.render_parcels(list(self.parcels.distinct().all()))      def get_town_centroid(self): -        q = self.towns.filter(center__isnull=False).annotate( -            centroid=Centroid(Union('center'))).all() +        q = ( +            self.towns.filter(center__isnull=False) +            .annotate(centroid=Centroid(Union("center"))) +            .all() +        )          if not q.count():              return          return q.all()[0].centroid, self._meta.verbose_name      def get_town_polygons(self): -        q = self.towns.filter(limit__isnull=False).annotate( -            poly=Union('limit')).all() +        q = self.towns.filter(limit__isnull=False).annotate(poly=Union("limit")).all()          if not q.count():              return None          return q.all()[0].poly, self._meta.verbose_name      def context_record_relations_q(self): -        from archaeological_context_records.models \ -            import RecordRelations as CRRL +        from archaeological_context_records.models import RecordRelations as CRRL +          return CRRL.objects.filter(left_record__operation=self)      def context_record_docs_q(self): -        return Document.objects.filter( -            context_records__operation=self) +        return Document.objects.filter(context_records__operation=self)      def find_docs_q(self):          return Document.objects.filter( -            finds__base_finds__context_record__operation=self) +            finds__base_finds__context_record__operation=self +        )      def containers_q(self):          from archaeological_warehouse.models import Container +          return Container.objects.filter(              finds__base_finds__context_record__operation=self          ) @@ -1465,18 +1631,29 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          actions = super(Operation, self).get_extra_actions(request)          is_locked = self.is_locked(request.user) -        can_edit_operation = self.can_do(request, 'change_operation') +        can_edit_operation = self.can_do(request, "change_operation")          if can_edit_operation:              actions += [ -                (reverse("operation-qa-duplicate", args=[self.pk]), -                 _("Duplicate"), "fa fa-clone", "", "", True), +                ( +                    reverse("operation-qa-duplicate", args=[self.pk]), +                    _("Duplicate"), +                    "fa fa-clone", +                    "", +                    "", +                    True, +                ),              ] -        can_add_cr = self.can_do(request, 'add_contextrecord') +        can_add_cr = self.can_do(request, "add_contextrecord")          if can_add_cr and not is_locked:              actions += [ -                (reverse('operation-qa-contextrecord', args=[self.pk]), -                 _("Add context record"), "fa fa-plus", -                 _("context record"), "", True), +                ( +                    reverse("operation-qa-contextrecord", args=[self.pk]), +                    _("Add context record"), +                    "fa fa-plus", +                    _("context record"), +                    "", +                    True, +                ),              ]          return actions @@ -1491,8 +1668,9 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @classmethod      def get_available_operation_code(cls, year=None): -        max_val = cls.objects.filter(year=year).aggregate( -            Max('operation_code'))["operation_code__max"] +        max_val = cls.objects.filter(year=year).aggregate(Max("operation_code"))[ +            "operation_code__max" +        ]          return (max_val + 1) if max_val else 1      year_index_lbl = _("Operation code") @@ -1504,14 +1682,17 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          lbl = str(self.operation_code)          year = self.year or 0          profile = get_current_profile() -        lbl = profile.default_operation_prefix \ -            + "%d-%s%s" % (year, (3 - len(lbl)) * "0", lbl) +        lbl = profile.default_operation_prefix + "%d-%s%s" % ( +            year, +            (3 - len(lbl)) * "0", +            lbl, +        )          return lbl      @property      def full_code_patriarche(self):          if not self.code_patriarche: -            return '' +            return ""          profile = get_current_profile()          return profile.operation_prefix + self.code_patriarche @@ -1519,12 +1700,14 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          if not self.operation_code:              return          objs = self.__class__.objects.filter( -            year=self.year, operation_code=self.operation_code) +            year=self.year, operation_code=self.operation_code +        )          if self.pk:              objs = objs.exclude(pk=self.pk)          if objs.count(): -            raise ValidationError(_("This operation code already exists for " -                                    "this year")) +            raise ValidationError( +                _("This operation code already exists for " "this year") +            )      @property      def surface_ha(self): @@ -1542,39 +1725,41 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,          profile = ishtaruser.current_profile          town_ids = []          if profile: -            town_ids = [town['pk'] -                        for town in profile.query_towns.values('pk').all()] +            town_ids = [town["pk"] for town in profile.query_towns.values("pk").all()]          query_owns = [              { -                'in_charge': ishtaruser.person, -                'scientist': ishtaruser.person, -                'collaborators__pk': ishtaruser.person.pk, -                'history_creator': ishtaruser.user_ptr, -                'towns__pk__in': town_ids, +                "in_charge": ishtaruser.person, +                "scientist": ishtaruser.person, +                "collaborators__pk": ishtaruser.person.pk, +                "history_creator": ishtaruser.user_ptr, +                "towns__pk__in": town_ids,              }, -            { -                'end_date__isnull': True -            } +            {"end_date__isnull": True},          ]          if not no_rel: -            query_owns[0]['archaeological_sites__collaborators__pk'] = \ -                ishtaruser.person.pk +            query_owns[0][ +                "archaeological_sites__collaborators__pk" +            ] = ishtaruser.person.pk          return query_owns      @classmethod      def get_query_owns(cls, ishtaruser):          from archaeological_warehouse.models import Warehouse -        q = cls._construct_query_own( -            'context_record__base_finds__find__container__responsible__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'context_record__base_finds__find__container__location__', -            Warehouse._get_query_owns_dicts(ishtaruser) -        ) | cls._construct_query_own( -            'context_record__base_finds__find__basket__', -            [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}] -        ) | cls._construct_query_own( -            '', cls._get_query_owns_dicts(ishtaruser) + +        q = ( +            cls._construct_query_own( +                "context_record__base_finds__find__container__responsible__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "context_record__base_finds__find__container__location__", +                Warehouse._get_query_owns_dicts(ishtaruser), +            ) +            | cls._construct_query_own( +                "context_record__base_finds__find__basket__", +                [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}], +            ) +            | cls._construct_query_own("", cls._get_query_owns_dicts(ishtaruser))          )          return q @@ -1594,7 +1779,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @property      def nb_acts(self, update=False):          _("Number of administrative acts") -        return self._get_or_set_stats('_nb_acts', update) +        return self._get_or_set_stats("_nb_acts", update)      def _nb_acts(self):          return self.administrative_act.count() @@ -1602,7 +1787,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @property      def nb_indexed_acts(self, update=False):          _("Number of indexed administrative acts") -        return self._get_or_set_stats('_nb_indexed_acts', update) +        return self._get_or_set_stats("_nb_indexed_acts", update)      def _nb_indexed_acts(self):          return self.administrative_act.filter(act_type__indexed=True).count() @@ -1610,136 +1795,182 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,      @property      def nb_context_records(self, update=False):          _("Number of context records") -        return self._get_or_set_stats('_nb_context_records', update) +        return self._get_or_set_stats("_nb_context_records", update)      def _nb_context_records(self):          return self.context_record.count()      @property      def nb_context_records_by_type(self, update=False): -        return self._get_or_set_stats('_nb_context_records_by_type', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_nb_context_records_by_type", update, expected_type=list +        )      def _nb_context_records_by_type(self):          nbs = [] -        q = self.context_record.values( -            'unit', 'unit__label').distinct().order_by('label') +        q = ( +            self.context_record.values("unit", "unit__label") +            .distinct() +            .order_by("label") +        )          for res in q.all(): -            nbs.append((str(res['unit__label'] or "-"), -                        self.context_record.filter(unit=res['unit']).count())) +            nbs.append( +                ( +                    str(res["unit__label"] or "-"), +                    self.context_record.filter(unit=res["unit"]).count(), +                ) +            )          return list(set(nbs))      @property      def nb_context_records_by_periods(self, update=False): -        return self._get_or_set_stats('_nb_context_records_by_periods', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_nb_context_records_by_periods", update, expected_type=list +        )      def _nb_context_records_by_periods(self):          nbs = [] -        q = self.context_record.values( -            'datings__period', 'datings__period__label').distinct().order_by( -                'datings__period__order') +        q = ( +            self.context_record.values("datings__period", "datings__period__label") +            .distinct() +            .order_by("datings__period__order") +        )          for res in q.all(): -            nbs.append((str(res['datings__period__label'] or "-"), -                        self.context_record.filter( -                            datings__period=res['datings__period']).count())) +            nbs.append( +                ( +                    str(res["datings__period__label"] or "-"), +                    self.context_record.filter( +                        datings__period=res["datings__period"] +                    ).count(), +                ) +            )          return nbs      @property      def nb_finds(self, update=False):          _("Number of finds") -        return self._get_or_set_stats('_nb_finds', update) +        return self._get_or_set_stats("_nb_finds", update)      def _nb_finds(self):          from archaeological_finds.models import Find +          q = Find.objects.filter(              base_finds__context_record__operation=self, -            upstream_treatment_id__isnull=True).distinct() +            upstream_treatment_id__isnull=True, +        ).distinct()          return q.count()      @property      def nb_finds_by_material_type(self, update=False): -        return self._get_or_set_stats('_nb_finds_by_material_type', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_nb_finds_by_material_type", update, expected_type=list +        )      def _nb_finds_by_material_type(self):          from archaeological_finds.models import Find +          nbs = [] -        q = Find.objects.filter( -            upstream_treatment_id__isnull=True, -            base_finds__context_record__operation=self).distinct().values( -            'material_types__pk', 'material_types__label').distinct().order_by( -            'material_types__label') +        q = ( +            Find.objects.filter( +                upstream_treatment_id__isnull=True, +                base_finds__context_record__operation=self, +            ) +            .distinct() +            .values("material_types__pk", "material_types__label") +            .distinct() +            .order_by("material_types__label") +        )          for res in q.all():              nbs.append( -                (str(res['material_types__label'] or "-"), -                 Find.objects.filter( -                    base_finds__context_record__operation=self, -                    upstream_treatment_id__isnull=True, -                    material_types__pk=res['material_types__pk']).count())) +                ( +                    str(res["material_types__label"] or "-"), +                    Find.objects.filter( +                        base_finds__context_record__operation=self, +                        upstream_treatment_id__isnull=True, +                        material_types__pk=res["material_types__pk"], +                    ).count(), +                ) +            )          return nbs      @property      def nb_finds_by_types(self, update=False): -        return self._get_or_set_stats('_nb_finds_by_types', update, -                                      expected_type=list) +        return self._get_or_set_stats("_nb_finds_by_types", update, expected_type=list)      def _nb_finds_by_types(self):          from archaeological_finds.models import Find +          nbs = [] -        q = Find.objects.filter( -            base_finds__context_record__operation=self).values( -            'object_types', 'object_types__label').distinct().order_by( -                'object_types__label') +        q = ( +            Find.objects.filter(base_finds__context_record__operation=self) +            .values("object_types", "object_types__label") +            .distinct() +            .order_by("object_types__label") +        )          for res in q.all(): -            label = str(res['object_types__label']) -            if label == 'None': +            label = str(res["object_types__label"]) +            if label == "None":                  label = str(_("No type"))              nbs.append( -                (label, -                 Find.objects.filter( -                     base_finds__context_record__operation=self, -                     upstream_treatment_id__isnull=True, -                     object_types=res['object_types']).count())) +                ( +                    label, +                    Find.objects.filter( +                        base_finds__context_record__operation=self, +                        upstream_treatment_id__isnull=True, +                        object_types=res["object_types"], +                    ).count(), +                ) +            )          return nbs      @property      def nb_finds_by_periods(self, update=False): -        return self._get_or_set_stats('_nb_finds_by_periods', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_nb_finds_by_periods", update, expected_type=list +        )      def _nb_finds_by_periods(self):          from archaeological_finds.models import Find +          nbs = [] -        q = Find.objects.filter( -            base_finds__context_record__operation=self).values( -            'datings__period', 'datings__period__label').distinct().order_by( -                'datings__period__order') +        q = ( +            Find.objects.filter(base_finds__context_record__operation=self) +            .values("datings__period", "datings__period__label") +            .distinct() +            .order_by("datings__period__order") +        )          for res in q.all():              nbs.append( -                (str(res['datings__period__label'] or "-"), -                 Find.objects.filter( -                    base_finds__context_record__operation=self, -                    upstream_treatment_id__isnull=True, -                    datings__period=res['datings__period']).count())) +                ( +                    str(res["datings__period__label"] or "-"), +                    Find.objects.filter( +                        base_finds__context_record__operation=self, +                        upstream_treatment_id__isnull=True, +                        datings__period=res["datings__period"], +                    ).count(), +                ) +            )          return nbs      @property      def nb_documents(self, update=False):          _("Number of sources") -        return self._get_or_set_stats('_nb_documents', update) +        return self._get_or_set_stats("_nb_documents", update)      def _nb_documents(self): -        return self.documents.count() + \ -            Document.objects.filter( -                context_records__operation=self).count() + \ -            Document.objects.filter( -                finds__base_finds__context_record__operation=self).count() +        return ( +            self.documents.count() +            + Document.objects.filter(context_records__operation=self).count() +            + Document.objects.filter( +                finds__base_finds__context_record__operation=self +            ).count() +        )      @property      def nb_documents_by_types(self, update=False): -        return self._get_or_set_stats('_nb_documents_by_types', update, -                                      expected_type=list) +        return self._get_or_set_stats( +            "_nb_documents_by_types", update, expected_type=list +        )      def _nb_documents_by_types(self):          docs = {} @@ -1749,20 +1980,23 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,              Document.objects.filter(context_records__operation=self),              Document.objects.filter(                  finds__upstream_treatment_id__isnull=True, -                finds__base_finds__context_record__operation=self)] +                finds__base_finds__context_record__operation=self, +            ), +        ]          for q in qs: -            for st in set(q.values_list('source_type_id', -                                        flat=True).distinct()): +            for st in set(q.values_list("source_type_id", flat=True).distinct()):                  if st not in docs:                      docs[st] = 0                  docs[st] += q.filter(source_type_id=st).count() -        docs = [(str(SourceType.objects.get(pk=k)) -                 if k else str(_("No type")), docs[k]) for k in docs] +        docs = [ +            (str(SourceType.objects.get(pk=k)) if k else str(_("No type")), docs[k]) +            for k in docs +        ]          return list(sorted(docs, key=lambda x: x[0]))      @property      def nb_stats_finds_by_ue(self, update=False): -        return self._get_or_set_stats('_nb_stats_finds_by_ue', update) +        return self._get_or_set_stats("_nb_stats_finds_by_ue", update)      def _nb_stats_finds_by_ue(self):          _("Mean") @@ -1771,10 +2005,10 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,              finds.append(cr.base_finds.count())          if not finds:              return res -        res['mean'] = float(sum(finds)) / max(len(finds), 1) -        res['min'] = min(finds) -        res['max'] = max(finds) -        res['mode'] = " ; ".join([str(m) for m in mode(finds)]) +        res["mean"] = float(sum(finds)) / max(len(finds), 1) +        res["min"] = min(finds) +        res["max"] = max(finds) +        res["mode"] = " ; ".join([str(m) for m in mode(finds)])          return res      def save(self, *args, **kwargs): @@ -1783,7 +2017,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,              self.year = self.start_date.year          if self.operation_code is None:              self.operation_code = self.get_available_operation_code(self.year) -        if hasattr(self, 'code_patriarche'): +        if hasattr(self, "code_patriarche"):              self.code_patriarche = self.code_patriarche or ""          item = super(Operation, self).save(*args, **kwargs)          self.clean_parcel_duplicates() @@ -1791,20 +2025,20 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem,  m2m_changed.connect(force_cached_label_changed, sender=Operation.towns.through) -m2m_changed.connect(document_attached_changed, -                    sender=Operation.documents.through) +m2m_changed.connect(document_attached_changed, sender=Operation.documents.through)  for attr in Operation.HISTORICAL_M2M: -    m2m_changed.connect(m2m_historization_changed, -                        sender=getattr(Operation, attr).through) +    m2m_changed.connect( +        m2m_historization_changed, sender=getattr(Operation, attr).through +    )  def operation_post_save(sender, **kwargs): -    if not kwargs['instance']: +    if not kwargs["instance"]:          return      post_save_geo(sender=sender, **kwargs) -    operation = kwargs['instance'] +    operation = kwargs["instance"]      operation.skip_history_when_saving = True      if operation.fnap_financing and operation.cost:          fnap_cost = int(float(operation.cost) / 100 * operation.fnap_financing) @@ -1835,11 +2069,10 @@ post_save.connect(operation_post_save, sender=Operation)  class RelationType(GeneralRelationType): -      class Meta:          verbose_name = _("Operation relation type")          verbose_name_plural = _("Operation relation types") -        ordering = ('order', 'label') +        ordering = ("order", "label")  class OperationRecordRelationManager(models.Manager): @@ -1847,30 +2080,35 @@ class OperationRecordRelationManager(models.Manager):          return self.get(              left_record__uuid=left_record,              right_record__uuid=right_record, -            relation_type__txt_idx=relation_type) +            relation_type__txt_idx=relation_type, +        )  class RecordRelations(GeneralRecordRelations, models.Model): -    MAIN_ATTR = 'left_record' -    left_record = models.ForeignKey(Operation, -                                    related_name='right_relations') -    right_record = models.ForeignKey(Operation, -                                     related_name='left_relations') +    MAIN_ATTR = "left_record" +    left_record = models.ForeignKey(Operation, related_name="right_relations") +    right_record = models.ForeignKey(Operation, related_name="left_relations")      relation_type = models.ForeignKey(RelationType)      objects = OperationRecordRelationManager()      class Meta:          verbose_name = _("Operation record relation")          verbose_name_plural = _("Operation record relations") -        ordering = ('left_record__cached_label', 'relation_type', -                    'right_record__cached_label') +        ordering = ( +            "left_record__cached_label", +            "relation_type", +            "right_record__cached_label", +        )          permissions = [              ("view_operationrelation", "Can view all Operation relations"),          ]      def natural_key(self): -        return (self.left_record.uuid, -                self.right_record.uuid, self.relation_type.txt_idx) +        return ( +            self.left_record.uuid, +            self.right_record.uuid, +            self.relation_type.txt_idx, +        )  post_delete.connect(post_delete_record_relation, sender=RecordRelations) @@ -1880,6 +2118,7 @@ class OperationByDepartment(models.Model):      """      Database view for dashboard      """ +      CREATE_SQL = """      CREATE VIEW operation_department (id, department_id, operation_id) as          select town."id", town."departement_id", @@ -1897,257 +2136,279 @@ class OperationByDepartment(models.Model):      """      operation = models.ForeignKey(Operation, verbose_name=_("Operation")) -    department = models.ForeignKey(Department, verbose_name=_("Department"), -                                   on_delete=models.DO_NOTHING, -                                   blank=True, null=True) +    department = models.ForeignKey( +        Department, +        verbose_name=_("Department"), +        on_delete=models.DO_NOTHING, +        blank=True, +        null=True, +    )      class Meta:          managed = False -        db_table = 'operation_department' +        db_table = "operation_department"  class ActType(GeneralType): -    TYPE = (('F', _('Archaeological file')), -            ('O', _('Operation')), -            ('TF', _('Treatment request')), -            ('T', _('Treatment')), -            ) +    TYPE = ( +        ("F", _("Archaeological file")), +        ("O", _("Operation")), +        ("TF", _("Treatment request")), +        ("T", _("Treatment")), +    )      SERIALIZATION_EXCLUDE = ["associated_template"] -    intented_to = models.CharField(_("Intended to"), max_length=2, -                                   choices=TYPE) +    intented_to = models.CharField(_("Intended to"), max_length=2, choices=TYPE)      code = models.CharField(_("Code"), max_length=10, blank=True, null=True)      associated_template = models.ManyToManyField( -        DocumentTemplate, blank=True, -        verbose_name=_("Associated template"), related_name='acttypes') +        DocumentTemplate, +        blank=True, +        verbose_name=_("Associated template"), +        related_name="acttypes", +    )      indexed = models.BooleanField(_("Indexed"), default=False)      class Meta:          verbose_name = _("Act type")          verbose_name_plural = _("Act types") -        ordering = ('label',) +        ordering = ("label",)  post_save.connect(post_save_cache, sender=ActType)  post_delete.connect(post_save_cache, sender=ActType) -class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms, -                        ValueGetter): -    TABLE_COLS = ['full_ref', 'signature_date__year', 'index', 'act_type', -                  'act_object', 'signature_date', -                  'associated_file__cached_label', -                  'operation__cached_label', 'towns_label'] +class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms, ValueGetter): +    TABLE_COLS = [ +        "full_ref", +        "signature_date__year", +        "index", +        "act_type", +        "act_object", +        "signature_date", +        "associated_file__cached_label", +        "operation__cached_label", +        "towns_label", +    ]      SLUG = "administrativeact"      TABLE_COLS_FILE = [ -        'full_ref', 'year', 'index', 'act_type', -        'act_object', 'associated_file', 'towns_label', +        "full_ref", +        "year", +        "index", +        "act_type", +        "act_object", +        "associated_file", +        "towns_label", +    ] +    TABLE_COLS_OPE = [ +        "full_ref", +        "year", +        "index", +        "act_type", +        "operation", +        "act_object", +        "towns_label",      ] -    TABLE_COLS_OPE = ['full_ref', 'year', 'index', 'act_type', 'operation', -                      'act_object', 'towns_label'] -    if settings.COUNTRY == 'fr': -        TABLE_COLS.append('departments_label') -        TABLE_COLS_FILE.append('departments_label') -        TABLE_COLS_OPE.append('departments_label') +    if settings.COUNTRY == "fr": +        TABLE_COLS.append("departments_label") +        TABLE_COLS_FILE.append("departments_label") +        TABLE_COLS_OPE.append("departments_label")      # search parameters -    DATED_FIELDS = ['signature_date__lte', 'signature_date__gte'] +    DATED_FIELDS = ["signature_date__lte", "signature_date__gte"]      ASSOCIATED_MODELS = [ -        ('File', 'associated_file'), -        (Person, 'associated_file__general_contractor')] +        ("File", "associated_file"), +        (Person, "associated_file__general_contractor"), +    ]      EXTRA_REQUEST_KEYS = { -        'act_object': 'act_object__icontains', -        'act_type__intented_to': 'act_type__intented_to', -        'associated_file__general_contractor__attached_to': -            'associated_file__general_contractor__attached_to__pk', -        'associated_file__name': 'associated_file__name__icontains', -        'associated_file__operations__code_patriarche': -        'associated_file__operations__code_patriarche', -        'associated_file__permit_reference': -            'associated_file__permit_reference__icontains', -        'associated_file__towns': 'associated_file__towns__pk', -        'associated_file__towns__numero_insee__startswith': -        'associated_file__towns__numero_insee__startswith', -        'indexed': 'index__isnull', -        'history_creator': -        'history_creator__ishtaruser__person__pk', -        'history_modifier': -        'history_modifier__ishtaruser__person__pk', -        'operation__code_patriarche': 'operation__code_patriarche', -        'operation__towns': 'operation__towns__pk', -        'operation__towns__numero_insee__startswith': -        'operation__towns__numero_insee__startswith', -        'parcel_0': ('associated_file__parcels__section', -                     'operation__parcels__section', -                     'operation__associated_file__parcels__section'), -        'parcel_1': ( -            'associated_file__parcels__parcel_number' -            'operation__parcels__parcel_number', -            'operation__associated_file__parcels__parcel_number'), -        'parcel_2': ( -            'associated_file__parcels__public_domain', -            'operation__parcels__public_domain', -            'operation__associated_file__parcels__public_domain'), -        'signature_date_before': 'signature_date__lte', -        'signature_date_after': 'signature_date__gte', -        'year': 'signature_date__year', +        "act_object": "act_object__icontains", +        "act_type__intented_to": "act_type__intented_to", +        "associated_file__general_contractor__attached_to": "associated_file__general_contractor__attached_to__pk", +        "associated_file__name": "associated_file__name__icontains", +        "associated_file__operations__code_patriarche": "associated_file__operations__code_patriarche", +        "associated_file__permit_reference": "associated_file__permit_reference__icontains", +        "associated_file__towns": "associated_file__towns__pk", +        "associated_file__towns__numero_insee__startswith": "associated_file__towns__numero_insee__startswith", +        "indexed": "index__isnull", +        "history_creator": "history_creator__ishtaruser__person__pk", +        "history_modifier": "history_modifier__ishtaruser__person__pk", +        "operation__code_patriarche": "operation__code_patriarche", +        "operation__towns": "operation__towns__pk", +        "operation__towns__numero_insee__startswith": "operation__towns__numero_insee__startswith", +        "parcel_0": ( +            "associated_file__parcels__section", +            "operation__parcels__section", +            "operation__associated_file__parcels__section", +        ), +        "parcel_1": ( +            "associated_file__parcels__parcel_number" +            "operation__parcels__parcel_number", +            "operation__associated_file__parcels__parcel_number", +        ), +        "parcel_2": ( +            "associated_file__parcels__public_domain", +            "operation__parcels__public_domain", +            "operation__associated_file__parcels__public_domain", +        ), +        "signature_date_before": "signature_date__lte", +        "signature_date_after": "signature_date__gte", +        "year": "signature_date__year",      }      REVERSED_BOOL_FIELDS = [ -        'index__isnull', 'documents__image__isnull', -        'documents__associated_url__isnull', -        'documents__associated_file__isnull', +        "index__isnull", +        "documents__image__isnull", +        "documents__associated_url__isnull", +        "documents__associated_file__isnull", +    ] +    RELATIVE_SESSION_NAMES = [ +        ("operation", "operation__pk"), +        ("file", "associated_file__pk"),      ] -    RELATIVE_SESSION_NAMES = [('operation', 'operation__pk'), -                              ('file', 'associated_file__pk')]      COL_LABELS = { -        'full_ref': _("Ref."), 'signature_date__year': _("Year"), -        'associated_file__cached_label': _("Archaeological file"), -        'operation__cached_label': _("Operation"), +        "full_ref": _("Ref."), +        "signature_date__year": _("Year"), +        "associated_file__cached_label": _("Archaeological file"), +        "operation__cached_label": _("Operation"),      }      BASE_SEARCH_VECTORS = [          SearchVectorConfig("act_type__label"), -        SearchVectorConfig("act_object", 'local'), +        SearchVectorConfig("act_object", "local"),          SearchVectorConfig("towns_label"),      ]      INT_SEARCH_VECTORS = [          SearchVectorConfig("year"),          SearchVectorConfig("index"),      ] -    PARENT_SEARCH_VECTORS = ['operator', 'scientist', 'signatory', -                             'associated_file', 'operation', 'treatment_file', -                             'treatment'] +    PARENT_SEARCH_VECTORS = [ +        "operator", +        "scientist", +        "signatory", +        "associated_file", +        "operation", +        "treatment_file", +        "treatment", +    ]      # alternative names of fields for searches      ALT_NAMES = { -        'year': SearchAltName( -            pgettext_lazy("key for text search", "year"), -            'signature_date__year' -        ), -        'index': SearchAltName( -            pgettext_lazy("key for text search", "index"), -            'index' +        "year": SearchAltName( +            pgettext_lazy("key for text search", "year"), "signature_date__year"          ), -        'ref_sra': SearchAltName( -            pgettext_lazy("key for text search", "other-ref"), -            'ref_sra__iexact' +        "index": SearchAltName(pgettext_lazy("key for text search", "index"), "index"), +        "ref_sra": SearchAltName( +            pgettext_lazy("key for text search", "other-ref"), "ref_sra__iexact"          ), -        'operation__code_patriarche': SearchAltName( +        "operation__code_patriarche": SearchAltName(              pgettext_lazy("key for text search", "patriarche"), -            'operation__code_patriarche' +            "operation__code_patriarche",          ), -        'act_type': SearchAltName( -            pgettext_lazy("key for text search", "type"), -            'act_type__label__iexact' +        "act_type": SearchAltName( +            pgettext_lazy("key for text search", "type"), "act_type__label__iexact"          ), -        'indexed': SearchAltName( -            pgettext_lazy("key for text search", "indexed"), -            'index__isnull' +        "indexed": SearchAltName( +            pgettext_lazy("key for text search", "indexed"), "index__isnull"          ), -        'operation__towns': SearchAltName( +        "operation__towns": SearchAltName(              pgettext_lazy("key for text search", "operation-town"), -            'operation__towns__cached_label__iexact' +            "operation__towns__cached_label__iexact",          ), -        'associated_file__towns': SearchAltName( +        "associated_file__towns": SearchAltName(              pgettext_lazy("key for text search", "file-town"), -            'associated_file__towns__cached_label__iexact' +            "associated_file__towns__cached_label__iexact",          ), -        'parcel': SearchAltName( +        "parcel": SearchAltName(              pgettext_lazy("key for text search", "parcel"), -            ('associated_file__parcels__cached_label__iexact', -             'operation__parcels__cached_label__iexact', -             'operation__associated_file__parcels__cached_label__iexact'), +            ( +                "associated_file__parcels__cached_label__iexact", +                "operation__parcels__cached_label__iexact", +                "operation__associated_file__parcels__cached_label__iexact", +            ),          ), -        'operation__towns__numero_insee__startswith': SearchAltName( +        "operation__towns__numero_insee__startswith": SearchAltName(              pgettext_lazy("key for text search", "operation-department"), -            'operation__towns__numero_insee__startswith' +            "operation__towns__numero_insee__startswith",          ), -        'associated_file__towns__numero_insee__startswith': SearchAltName( +        "associated_file__towns__numero_insee__startswith": SearchAltName(              pgettext_lazy("key for text search", "file-department"), -            'associated_file__towns__numero_insee__startswith' +            "associated_file__towns__numero_insee__startswith",          ), -        'act_object': SearchAltName( -            pgettext_lazy("key for text search", "object"), -            'act_object__icontains' +        "act_object": SearchAltName( +            pgettext_lazy("key for text search", "object"), "act_object__icontains"          ), -        'signature_date_before': SearchAltName( +        "signature_date_before": SearchAltName(              pgettext_lazy("key for text search", "signature-before"), -            'signature_date__lte' +            "signature_date__lte",          ), -        'signature_date_after': SearchAltName( +        "signature_date_after": SearchAltName(              pgettext_lazy("key for text search", "signature-after"), -            'signature_date__gte' +            "signature_date__gte",          ), -        'associated_file__name': SearchAltName( +        "associated_file__name": SearchAltName(              pgettext_lazy("key for text search", "file-name"), -            'associated_file__name__icontains' +            "associated_file__name__icontains",          ), -        'associated_file__general_contractor': SearchAltName( +        "associated_file__general_contractor": SearchAltName(              pgettext_lazy("key for text search", "general-contractor"), -            'associated_file__general_contractor__cached_label__iexact' +            "associated_file__general_contractor__cached_label__iexact",          ), -        'associated_file__general_contractor__attached_to': SearchAltName( -            pgettext_lazy("key for text search", -                          "general-contractor-organization"), -            'associated_file__general_contractor__attached_to' -            '__cached_label__iexact' +        "associated_file__general_contractor__attached_to": SearchAltName( +            pgettext_lazy("key for text search", "general-contractor-organization"), +            "associated_file__general_contractor__attached_to" "__cached_label__iexact",          ), -        'associated_file__numeric_reference': SearchAltName( +        "associated_file__numeric_reference": SearchAltName(              pgettext_lazy("key for text search", "file-reference"), -            'associated_file__numeric_reference' +            "associated_file__numeric_reference",          ), -        'associated_file__year': SearchAltName( -            pgettext_lazy("key for text search", "file-year"), -            'associated_file__year' +        "associated_file__year": SearchAltName( +            pgettext_lazy("key for text search", "file-year"), "associated_file__year"          ), -        'associated_file__internal_reference': SearchAltName( +        "associated_file__internal_reference": SearchAltName(              pgettext_lazy("key for text search", "file-other-reference"), -            'associated_file__internal_reference__iexact' +            "associated_file__internal_reference__iexact",          ), -        'associated_file__in_charge': SearchAltName( +        "associated_file__in_charge": SearchAltName(              pgettext_lazy("key for text search", "file-in-charge"), -            'associated_file__in_charge__cached_label__iexact' +            "associated_file__in_charge__cached_label__iexact",          ), -        'associated_file__permit_reference': SearchAltName( +        "associated_file__permit_reference": SearchAltName(              pgettext_lazy("key for text search", "file-permit-reference"), -            'associated_file__permit_reference__iexact' +            "associated_file__permit_reference__iexact",          ), -        'treatment__name': SearchAltName( +        "treatment__name": SearchAltName(              pgettext_lazy("key for text search", "treatment-name"), -            'treatment__label__icontains' +            "treatment__label__icontains",          ), -        'treatment__other_reference': SearchAltName( +        "treatment__other_reference": SearchAltName(              pgettext_lazy("key for text search", "treatment-reference"), -            'treatment__other_reference__icontains' +            "treatment__other_reference__icontains",          ), -        'treatment__year': SearchAltName( -            pgettext_lazy("key for text search", "treatment-year"), -            'treatment__year' +        "treatment__year": SearchAltName( +            pgettext_lazy("key for text search", "treatment-year"), "treatment__year"          ), -        'treatment__index': SearchAltName( -            pgettext_lazy("key for text search", "treatment-index"), -            'treatment__index' +        "treatment__index": SearchAltName( +            pgettext_lazy("key for text search", "treatment-index"), "treatment__index"          ), -        'treatment__treatment_types': SearchAltName( +        "treatment__treatment_types": SearchAltName(              pgettext_lazy("key for text search", "treatment-type"), -            'treatment__treatment_types__label__iexact' +            "treatment__treatment_types__label__iexact",          ), -        'treatment_file__name': SearchAltName( +        "treatment_file__name": SearchAltName(              pgettext_lazy("key for text search", "treatment-file-name"), -            'treatment_file__name__icontains' +            "treatment_file__name__icontains",          ), -        'treatment_file__internal_reference': SearchAltName( +        "treatment_file__internal_reference": SearchAltName(              pgettext_lazy("key for text search", "treatment-file-reference"), -            'treatment_file__internal_reference__icontains' +            "treatment_file__internal_reference__icontains",          ), -        'treatment_file__year': SearchAltName( +        "treatment_file__year": SearchAltName(              pgettext_lazy("key for text search", "treatment-file-year"), -            'treatment_file__year' +            "treatment_file__year",          ), -        'treatment_file__index': SearchAltName( +        "treatment_file__index": SearchAltName(              pgettext_lazy("key for text search", "treatment-file-index"), -            'treatment_file__index' +            "treatment_file__index",          ), -        'treatment_file__type': SearchAltName( +        "treatment_file__type": SearchAltName(              pgettext_lazy("key for text search", "treatment-file-type"), -            'treatment_file__type__label__iexact' +            "treatment_file__type__label__iexact",          ),      }      ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) @@ -2156,102 +2417,134 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,      UP_MODEL_QUERY = {}      POST_PROCESS_REQUEST = { -        'operation__towns__numero_insee__startswith': '_get_department_code', -        'associated_file__towns__numero_insee__startswith': -            '_get_department_code', +        "operation__towns__numero_insee__startswith": "_get_department_code", +        "associated_file__towns__numero_insee__startswith": "_get_department_code",      }      # fields      act_type = models.ForeignKey(ActType, verbose_name=_("Act type"))      in_charge = models.ForeignKey( -        Person, blank=True, null=True, -        related_name='adminact_operation_in_charge', +        Person, +        blank=True, +        null=True, +        related_name="adminact_operation_in_charge",          verbose_name=_("Person in charge of the operation"), -        on_delete=models.SET_NULL,) -    index = models.IntegerField(verbose_name=_("Index"), blank=True, -                                null=True) +        on_delete=models.SET_NULL, +    ) +    index = models.IntegerField(verbose_name=_("Index"), blank=True, null=True)      operator = models.ForeignKey( -        Organization, blank=True, null=True, +        Organization, +        blank=True, +        null=True,          verbose_name=_("Archaeological preventive operator"), -        related_name='adminact_operator', on_delete=models.SET_NULL) +        related_name="adminact_operator", +        on_delete=models.SET_NULL, +    )      scientist = models.ForeignKey( -        Person, blank=True, null=True, -        related_name='adminact_scientist', on_delete=models.SET_NULL, -        verbose_name=_("Scientist in charge")) +        Person, +        blank=True, +        null=True, +        related_name="adminact_scientist", +        on_delete=models.SET_NULL, +        verbose_name=_("Scientist in charge"), +    )      signatory = models.ForeignKey( -        Person, blank=True, null=True, related_name='signatory', -        verbose_name=_("Signatory"), on_delete=models.SET_NULL,) +        Person, +        blank=True, +        null=True, +        related_name="signatory", +        verbose_name=_("Signatory"), +        on_delete=models.SET_NULL, +    )      operation = models.ForeignKey( -        Operation, blank=True, null=True, -        related_name='administrative_act', verbose_name=_("Operation")) +        Operation, +        blank=True, +        null=True, +        related_name="administrative_act", +        verbose_name=_("Operation"), +    )      associated_file = models.ForeignKey( -        'archaeological_files.File', -        blank=True, null=True, -        related_name='administrative_act', -        verbose_name=_("Archaeological file")) +        "archaeological_files.File", +        blank=True, +        null=True, +        related_name="administrative_act", +        verbose_name=_("Archaeological file"), +    )      treatment_file = models.ForeignKey( -        'archaeological_finds.TreatmentFile', -        blank=True, null=True, -        related_name='administrative_act', -        verbose_name=_("Treatment request")) +        "archaeological_finds.TreatmentFile", +        blank=True, +        null=True, +        related_name="administrative_act", +        verbose_name=_("Treatment request"), +    )      treatment = models.ForeignKey( -        'archaeological_finds.Treatment', -        blank=True, null=True, -        related_name='administrative_act', -        verbose_name=_("Treatment")) -    signature_date = models.DateField(_("Signature date"), blank=True, -                                      null=True) +        "archaeological_finds.Treatment", +        blank=True, +        null=True, +        related_name="administrative_act", +        verbose_name=_("Treatment"), +    ) +    signature_date = models.DateField(_("Signature date"), blank=True, null=True)      year = models.IntegerField(_("Year"), blank=True, null=True)      act_object = models.TextField(_("Object"), blank=True, default="") -    if settings.COUNTRY == 'fr': -        ref_sra = models.CharField("Référence SRA", max_length=15, -                                   blank=True, null=True) +    if settings.COUNTRY == "fr": +        ref_sra = models.CharField( +            "Référence SRA", max_length=15, blank=True, null=True +        )          departments_label = models.TextField( -            _("Departments"), blank=True, default="", -            help_text=_("Cached values get from associated departments")) +            _("Departments"), +            blank=True, +            default="", +            help_text=_("Cached values get from associated departments"), +        )      towns_label = models.TextField( -        _("Towns"), blank=True, default="", -        help_text=_("Cached values get from associated towns")) +        _("Towns"), +        blank=True, +        default="", +        help_text=_("Cached values get from associated towns"), +    )      documents = models.ManyToManyField( -        Document, related_name="administrativeacts", -        verbose_name=_("Documents"), blank=True) +        Document, +        related_name="administrativeacts", +        verbose_name=_("Documents"), +        blank=True, +    )      main_image = models.ForeignKey( -        Document, related_name='main_image_administrativeacts', +        Document, +        related_name="main_image_administrativeacts",          on_delete=models.SET_NULL, -        verbose_name=_("Main image"), blank=True, null=True) +        verbose_name=_("Main image"), +        blank=True, +        null=True, +    )      history = HistoricalRecords() -    _prefix = 'adminact_' +    _prefix = "adminact_"      class Meta: -        ordering = ('year', 'signature_date', 'index', 'act_type') +        ordering = ("year", "signature_date", "index", "act_type")          verbose_name = _("Administrative act")          verbose_name_plural = _("Administrative acts")          permissions = ( -            ("view_administrativeact", -             "Can view all Administrative acts"), -            ("view_own_administrativeact", -             "Can view own Administrative act"), -            ("add_own_administrativeact", -             "Can add own Administrative act"), -            ("change_own_administrativeact", -             "Can change own Administrative act"), -            ("delete_own_administrativeact", -             "Can delete own Administrative act"), +            ("view_administrativeact", "Can view all Administrative acts"), +            ("view_own_administrativeact", "Can view own Administrative act"), +            ("add_own_administrativeact", "Can add own Administrative act"), +            ("change_own_administrativeact", "Can change own Administrative act"), +            ("delete_own_administrativeact", "Can delete own Administrative act"),          )          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      @property      def DELETE_URL(self):          if self.operation: -            return 'delete-administrativeact-operation' +            return "delete-administrativeact-operation"          if self.associated_file: -            return 'delete-administrativeact-file' +            return "delete-administrativeact-file"          if self.treatment: -            return 'delete-administrativeact-treatment' +            return "delete-administrativeact-treatment"          if self.treatment_file: -            return 'delete-administrativeact-treatmentfile' +            return "delete-administrativeact-treatmentfile"      def __str__(self):          lbl = "" @@ -2263,9 +2556,8 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,              lbl += " - "          lbl += self.act_type.label + " - "          return lbl + settings.JOINT.join( -            [str(item) for item in [ -                self.related_item, self.act_object] -             if item]) +            [str(item) for item in [self.related_item, self.act_object] if item] +        )      full_ref_lbl = _("Ref.") @@ -2281,7 +2573,7 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,              lbl.append(str(self.year))          if self.index:              lbl.append("n°%d" % self.index) -        if settings.COUNTRY == 'fr' and self.ref_sra: +        if settings.COUNTRY == "fr" and self.ref_sra:              lbl.append("[%s]" % self.ref_sra)          return " ".join(lbl) @@ -2299,21 +2591,21 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,      @property      def departments(self): -        if settings.COUNTRY != 'fr': -            return '' +        if settings.COUNTRY != "fr": +            return ""          q = None          if self.associated_file:              q = self.associated_file.towns.all()          elif self.operation:              q = self.operation.towns.all()          if not q: -            return '' +            return ""          dpts = []          for town in q:              dpt = town.numero_insee[:2]              if dpt not in dpts:                  dpts.append(dpt) -        return ', '.join(list(sorted(dpts))) +        return ", ".join(list(sorted(dpts)))      @classmethod      def _get_department_code(cls, value): @@ -2344,13 +2636,13 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,      def get_filename(self):          filename = self.related_item.associated_filename -        filename = "-".join(filename.split('-')[:-1])  # remove date +        filename = "-".join(filename.split("-")[:-1])  # remove date          if self.act_type.code:              filename += "-" + self.act_type.code          if self.signature_date and self.index:              filename += "-%d-%d" % (self.signature_date.year, self.index)          if self.signature_date: -            filename += "-" + self.signature_date.strftime('%Y%m%d') +            filename += "-" + self.signature_date.strftime("%Y%m%d")          return filename      def publish(self, template_pk=None): @@ -2369,20 +2661,21 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,          if not self.index:              c_index = 1              q = AdministrativeAct.objects.filter( -                act_type__indexed=True, signature_date__year=self.year, -                index__isnull=False).order_by("-index") +                act_type__indexed=True, +                signature_date__year=self.year, +                index__isnull=False, +            ).order_by("-index")              if q.count():                  c_index = q.all()[0].index + 1              self.index = c_index          conflict = AdministrativeAct.objects.filter( -            act_type__indexed=True, signature_date__year=self.year, -            index=self.index) +            act_type__indexed=True, signature_date__year=self.year, index=self.index +        )          if self.pk:              conflict = conflict.exclude(pk=self.pk)          if conflict.count():              if self.pk: -                raise ValidationError(_("This index already exists for " -                                        "this year")) +                raise ValidationError(_("This index already exists for " "this year"))              else:                  self._get_index() @@ -2396,14 +2689,13 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,          super(AdministrativeAct, self).clean(*args, **kwargs)      def save(self, *args, **kwargs): -        if settings.COUNTRY == 'fr': +        if settings.COUNTRY == "fr":              self.departments_label = self.departments -        self.towns_label = ", ".join( -            list(sorted([str(town) for town in self.towns]))) +        self.towns_label = ", ".join(list(sorted([str(town) for town in self.towns])))          force = False -        if 'force' in kwargs: -            force = kwargs.pop('force') +        if "force" in kwargs: +            force = kwargs.pop("force")          if self.signature_date:              self.year = self.signature_date.year @@ -2416,7 +2708,7 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,                      except:                          pass          super(AdministrativeAct, self).save(*args, **kwargs) -        if hasattr(self, 'associated_file') and self.associated_file: +        if hasattr(self, "associated_file") and self.associated_file:              self.associated_file.update_has_admin_act()              self.associated_file.update_short_menu_class()          updated = self.update_search_vector() @@ -2426,57 +2718,67 @@ class AdministrativeAct(DocumentItem, BaseHistorizedItem, OwnPerms,  def strip_zero(value):      for idx, nb in enumerate(value): -        if nb != '0': +        if nb != "0":              return value[idx:]      return value  class Parcel(LightHistorizedItem): -    EXTERNAL_ID_KEY = 'parcel_external_id' +    EXTERNAL_ID_KEY = "parcel_external_id"      BASE_SEARCH_VECTORS = [          SearchVectorConfig("section"),          SearchVectorConfig("parcel_number"),          SearchVectorConfig("cached_label"),      ] -    PARENT_SEARCH_VECTORS = ['operation'] +    PARENT_SEARCH_VECTORS = ["operation"]      objects = UUIDModelManager()      uuid = models.UUIDField(default=uuid.uuid4)      associated_file = models.ForeignKey( -        'archaeological_files.File', -        related_name='parcels', verbose_name=_("File"), -        blank=True, null=True, on_delete=models.SET_NULL) +        "archaeological_files.File", +        related_name="parcels", +        verbose_name=_("File"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL, +    )      operation = models.ForeignKey( -        Operation, related_name='parcels', blank=True, null=True, -        verbose_name=_("Operation"), on_delete=models.SET_NULL) +        Operation, +        related_name="parcels", +        blank=True, +        null=True, +        verbose_name=_("Operation"), +        on_delete=models.SET_NULL, +    )      year = models.IntegerField(_("Year"), blank=True, null=True) -    town = models.ForeignKey(Town, related_name='parcels', -                             verbose_name=_("Town")) -    section = models.CharField(_("Section"), max_length=4, -                               null=True, blank=True) -    parcel_number = models.CharField(_("Parcel number"), max_length=6, -                                     null=True, blank=True) +    town = models.ForeignKey(Town, related_name="parcels", verbose_name=_("Town")) +    section = models.CharField(_("Section"), max_length=4, null=True, blank=True) +    parcel_number = models.CharField( +        _("Parcel number"), max_length=6, null=True, blank=True +    )      public_domain = models.BooleanField(_("Public domain"), default=False) -    external_id = models.CharField(_("External ID"), max_length=100, -                                   null=True, blank=True) +    external_id = models.CharField( +        _("External ID"), max_length=100, null=True, blank=True +    )      auto_external_id = models.BooleanField( -        _("External ID is set automatically"), default=False) +        _("External ID is set automatically"), default=False +    )      address = models.TextField(_("Address - Locality"), blank=True, default="") -    cached_label = models.TextField(_("Cached name"), blank=True, default="", -                                    db_index=True) +    cached_label = models.TextField( +        _("Cached name"), blank=True, default="", db_index=True +    )      class Meta:          verbose_name = _("Parcel")          verbose_name_plural = _("Parcels") -        ordering = ('year', 'section', 'parcel_number') +        ordering = ("year", "section", "parcel_number")          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      @property      def short_label(self): -        items = [str(item) for item in [self.section, self.parcel_number] -                 if item] +        items = [str(item) for item in [self.section, self.parcel_number] if item]          if self.public_domain:              items.append(str(_("Public domain")))          return settings.JOINT.join(items) @@ -2485,7 +2787,7 @@ class Parcel(LightHistorizedItem):          return self.short_label      def natural_key(self): -        return (self.uuid, ) +        return (self.uuid,)      """      def merge(self, parcel): @@ -2519,9 +2821,11 @@ class Parcel(LightHistorizedItem):      @classmethod      def grouped_parcels(cls, parcels): -        sortkeyfn = lambda s: (getattr(s, 'town_id'), -                               getattr(s, 'section') or "", -                               getattr(s, 'year') or 0) +        sortkeyfn = lambda s: ( +            getattr(s, "town_id"), +            getattr(s, "section") or "", +            getattr(s, "year") or 0, +        )          parcels = sorted(parcels, key=sortkeyfn)          grouped = []          for keys, parcel_grp in groupby(parcels, key=sortkeyfn): @@ -2534,45 +2838,46 @@ class Parcel(LightHistorizedItem):                      if parcel.parcel_number == "0":                          nb = "0"                      else: -                        nb = "0" * (12 - len(parcel.parcel_number)) + \ -                            parcel.parcel_number +                        nb = ( +                            "0" * (12 - len(parcel.parcel_number)) +                            + parcel.parcel_number +                        )                  if parcel.public_domain:                      if nb:                          nb += " "                      nb += str(_("Public domain"))                  grouped[-1].parcel_numbers.append(nb)              grouped[-1].parcel_numbers.sort() -            grouped[-1].parcel_numbers = [strip_zero(n) -                                          for n in grouped[-1].parcel_numbers] +            grouped[-1].parcel_numbers = [ +                strip_zero(n) for n in grouped[-1].parcel_numbers +            ]          return grouped      @classmethod      def render_parcels(cls, parcels):          parcels = cls.grouped_parcels(parcels) -        res = '' -        c_town, c_section = '', '' +        res = "" +        c_town, c_section = "", ""          for idx, parcels in enumerate(parcels):              if c_town != str(parcels.town):                  c_town = str(parcels.town)                  if idx:                      res += " ; " -                res += str(parcels.town) + ' : ' +                res += str(parcels.town) + " : "              elif c_section:                  res += " / "              else:  # public domain                  res += " & "              c_section = parcels.section -            res += parcels.section + ' ' +            res += parcels.section + " "              res += ", ".join(parcels.parcel_numbers)              if parcels.year:                  res += " ({})".format(parcels.year)          return res      def long_label(self): -        items = [str(self.operation) or -                 str(self.associated_file) or ""] -        items += [str(item) for item in [self.section, self.parcel_number] -                  if item] +        items = [str(self.operation) or str(self.associated_file) or ""] +        items += [str(item) for item in [self.section, self.parcel_number] if item]          return settings.JOINT.join(items)      def copy_to_file(self): @@ -2582,20 +2887,26 @@ class Parcel(LightHistorizedItem):          if not self.operation or not self.operation.associated_file:              # not concerned              return -        keys = {'town': self.town, 'section': self.section, -                'parcel_number': self.parcel_number} +        keys = { +            "town": self.town, +            "section": self.section, +            "parcel_number": self.parcel_number, +        }          if self.operation.associated_file.parcels.filter(**keys).count():              # everything is OK              return -        keys['address'] = self.address -        keys['year'] = self.year -        keys['associated_file'] = self.operation.associated_file +        keys["address"] = self.address +        keys["year"] = self.year +        keys["associated_file"] = self.operation.associated_file          new_p = Parcel.objects.create(**keys)          # also copy owning          for owning in self.owners.all():              ParcelOwner.objects.create( -                owner=owning.owner, parcel=new_p, -                start_date=owning.start_date, end_date=owning.end_date) +                owner=owning.owner, +                parcel=new_p, +                start_date=owning.start_date, +                end_date=owning.end_date, +            )      def copy_to_operation(self):          """ @@ -2605,19 +2916,24 @@ class Parcel(LightHistorizedItem):          if not (self.operation and self.associated_file):              # everything is OK              return -        keys = {'town': self.town, 'section': self.section, -                'parcel_number': self.parcel_number, -                'operation': self.operation, -                'associated_file': None, -                'defaults': {'address': self.address, 'year': self.year} -                } +        keys = { +            "town": self.town, +            "section": self.section, +            "parcel_number": self.parcel_number, +            "operation": self.operation, +            "associated_file": None, +            "defaults": {"address": self.address, "year": self.year}, +        }          new_p, created = Parcel.objects.get_or_create(**keys)          # copy owning only if created          if created:              for owning in self.owners.all():                  ParcelOwner.objects.create( -                    owner=owning.owner, parcel=new_p, -                    start_date=owning.start_date, end_date=owning.end_date) +                    owner=owning.owner, +                    parcel=new_p, +                    start_date=owning.start_date, +                    end_date=owning.end_date, +                )          self.operation = None          self.save() @@ -2637,34 +2953,41 @@ class Parcel(LightHistorizedItem):  def parcel_post_save(sender, **kwargs): -    if not kwargs['instance']: +    if not kwargs["instance"]:          return -    parcel = kwargs['instance'] +    parcel = kwargs["instance"]      cached_label_changed(sender, **kwargs) -    if not getattr(parcel, '_updated_id', None) \ -            and not parcel.operation and not parcel.associated_file \ -            and parcel.context_record.count(): +    if ( +        not getattr(parcel, "_updated_id", None) +        and not parcel.operation +        and not parcel.associated_file +        and parcel.context_record.count() +    ):          # trying to restore a lost parcel          parcel.operation = parcel.context_record.all()[0].operation          parcel.save()          return      if parcel.context_record.count(): -        parcel.context_record.model.cached_label_bulk_update( -            parcel_id=parcel.id) +        parcel.context_record.model.cached_label_bulk_update(parcel_id=parcel.id) -    if parcel.operation and parcel.operation.pk and \ -            parcel.town not in list(parcel.operation.towns.all()): +    if ( +        parcel.operation +        and parcel.operation.pk +        and parcel.town not in list(parcel.operation.towns.all()) +    ):          try:              # multiple save can cause multiple add              with transaction.atomic():                  parcel.operation.towns.add(parcel.town)          except IntegrityError:              pass -    if parcel.associated_file and \ -            parcel.associated_file.pk and \ -            parcel.town not in list(parcel.associated_file.towns.all()): +    if ( +        parcel.associated_file +        and parcel.associated_file.pk +        and parcel.town not in list(parcel.associated_file.towns.all()) +    ):          try:              # multiple save can cause multiple add              with transaction.atomic(): @@ -2681,10 +3004,10 @@ post_save.connect(parcel_post_save, sender=Parcel)  class ParcelOwner(LightHistorizedItem):      uuid = models.UUIDField(default=uuid.uuid4) -    owner = models.ForeignKey(Person, verbose_name=_("Owner"), -                              related_name="parcel_owner") -    parcel = models.ForeignKey(Parcel, verbose_name=_("Parcel"), -                               related_name='owners') +    owner = models.ForeignKey( +        Person, verbose_name=_("Owner"), related_name="parcel_owner" +    ) +    parcel = models.ForeignKey(Parcel, verbose_name=_("Parcel"), related_name="owners")      start_date = models.DateField(_("Start date"))      end_date = models.DateField(_("End date"))      objects = UUIDModelManager() @@ -2693,14 +3016,14 @@ class ParcelOwner(LightHistorizedItem):          verbose_name = _("Parcel owner")          verbose_name_plural = _("Parcel owners")          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      def __str__(self):          return "{}{}{}".format(self.owner, settings.JOINT, self.parcel)      def natural_key(self): -        return (self.uuid, ) +        return (self.uuid,)      @property      def operation(self): @@ -2718,26 +3041,34 @@ class OperationDashboard:          self.total_number = main_dashboard.total_number          self.filters_keys = [ -            'recorded', 'effective', 'active', 'field', -            'documented', 'closed', 'documented_closed'] +            "recorded", +            "effective", +            "active", +            "field", +            "documented", +            "closed", +            "documented_closed", +        ]          filters = { -            'recorded': {}, -            'effective': {'scientist__isnull': False}, -            'active': {'scientist__isnull': False, 'end_date__isnull': True}, -            'field': {'excavation_end_date__isnull': True}, -            'documented': {'documents__isnull': False}, -            'documented_closed': {'documents__isnull': False, -                                  'end_date__isnull': False}, -            'closed': {'end_date__isnull': False} +            "recorded": {}, +            "effective": {"scientist__isnull": False}, +            "active": {"scientist__isnull": False, "end_date__isnull": True}, +            "field": {"excavation_end_date__isnull": True}, +            "documented": {"documents__isnull": False}, +            "documented_closed": { +                "documents__isnull": False, +                "end_date__isnull": False, +            }, +            "closed": {"end_date__isnull": False},          }          filters_label = { -            'recorded': _("Recorded"), -            'effective': _("Effective"), -            'active': _("Active"), -            'field': _("Field completed"), -            'documented': _("Associated report"), -            'closed': _("Closed"), -            'documented_closed': _("Documented and closed"), +            "recorded": _("Recorded"), +            "effective": _("Effective"), +            "active": _("Active"), +            "field": _("Field completed"), +            "documented": _("Associated report"), +            "closed": _("Closed"), +            "documented_closed": _("Documented and closed"),          }          self.filters_label = [filters_label[k] for k in self.filters_keys]          self.total = [] @@ -2746,22 +3077,25 @@ class OperationDashboard:              nb = Operation.objects.filter(**fltr).count()              self.total.append((lbl, nb)) -        self.surface_by_type = Operation.objects\ -            .values('operation_type__label')\ -            .annotate(number=Sum('surface'))\ -            .order_by('-number', 'operation_type__label') +        self.surface_by_type = ( +            Operation.objects.values("operation_type__label") +            .annotate(number=Sum("surface")) +            .order_by("-number", "operation_type__label") +        )          self.by_type = []          self.types = OperationType.objects.filter(available=True).all()          for fltr_key in self.filters_keys:              fltr, lbl = filters[fltr_key], filters_label[fltr_key] -            type_res = Operation.objects.filter(**fltr).\ -                values('operation_type', 'operation_type__label').\ -                annotate(number=Count('pk')).\ -                order_by('operation_type') +            type_res = ( +                Operation.objects.filter(**fltr) +                .values("operation_type", "operation_type__label") +                .annotate(number=Count("pk")) +                .order_by("operation_type") +            )              types_dct = {}              for typ in type_res.all(): -                types_dct[typ['operation_type']] = typ["number"] +                types_dct[typ["operation_type"]] = typ["number"]              types = []              for typ in self.types:                  if typ.pk in types_dct: @@ -2771,17 +3105,21 @@ class OperationDashboard:              self.by_type.append((lbl, types))          self.by_year = [] -        self.years = [res['year'] for res in Operation.objects.values('year') -                      .order_by('-year').distinct()] +        self.years = [ +            res["year"] +            for res in Operation.objects.values("year").order_by("-year").distinct() +        ]          for fltr_key in self.filters_keys:              fltr, lbl = filters[fltr_key], filters_label[fltr_key] -            year_res = Operation.objects.filter(**fltr)\ -                                        .values('year')\ -                                        .annotate(number=Count('pk'))\ -                                        .order_by('year') +            year_res = ( +                Operation.objects.filter(**fltr) +                .values("year") +                .annotate(number=Count("pk")) +                .order_by("year") +            )              years_dct = {}              for yr in year_res.all(): -                years_dct[yr['year']] = yr["number"] +                years_dct[yr["year"]] = yr["number"]              years = []              for yr in self.years:                  if yr in years_dct: @@ -2792,19 +3130,29 @@ class OperationDashboard:          self.by_realisation_year = []          self.realisation_years = [ -            res['date'] for res in Operation.objects.extra( -                {'date': "date_trunc('year', start_date)"}).values('date') -            .filter(start_date__isnull=False).order_by('-date').distinct()] +            res["date"] +            for res in Operation.objects.extra( +                {"date": "date_trunc('year', start_date)"} +            ) +            .values("date") +            .filter(start_date__isnull=False) +            .order_by("-date") +            .distinct() +        ]          for fltr_key in self.filters_keys:              fltr, lbl = filters[fltr_key], filters_label[fltr_key] -            year_res = Operation.objects.filter(**fltr).extra( -                {'date': "date_trunc('year', start_date)"}).values('date')\ -                .values('date').filter(start_date__isnull=False)\ -                .annotate(number=Count('pk'))\ -                .order_by('-date') +            year_res = ( +                Operation.objects.filter(**fltr) +                .extra({"date": "date_trunc('year', start_date)"}) +                .values("date") +                .values("date") +                .filter(start_date__isnull=False) +                .annotate(number=Count("pk")) +                .order_by("-date") +            )              years_dct = {}              for yr in year_res.all(): -                years_dct[yr['date']] = yr["number"] +                years_dct[yr["date"]] = yr["number"]              years = []              for yr in self.realisation_years:                  if yr in years_dct: @@ -2815,14 +3163,18 @@ class OperationDashboard:          self.effective = []          for typ in self.types: -            year_res = Operation.objects.filter(**{'scientist__isnull': False, -                                                   'operation_type': typ})\ -                                        .values('year')\ -                                        .annotate(number=Count('pk'))\ -                                        .order_by('-year').distinct() +            year_res = ( +                Operation.objects.filter( +                    **{"scientist__isnull": False, "operation_type": typ} +                ) +                .values("year") +                .annotate(number=Count("pk")) +                .order_by("-year") +                .distinct() +            )              years_dct = {}              for yr in year_res.all(): -                years_dct[yr['year']] = yr["number"] +                years_dct[yr["year"]] = yr["number"]              years = []              for yr in self.years:                  if yr in years_dct: @@ -2835,8 +3187,8 @@ class OperationDashboard:          now = datetime.date.today()          limit = datetime.date(now.year, now.month, 1) - datetime.timedelta(365)          by_realisation_month = Operation.objects.filter( -            start_date__gt=limit, start_date__isnull=False).extra( -                {'date': "date_trunc('month', start_date)"}) +            start_date__gt=limit, start_date__isnull=False +        ).extra({"date": "date_trunc('month', start_date)"})          self.last_months = []          date = datetime.datetime(now.year, now.month, 1)          for mt_idx in range(12): @@ -2848,8 +3200,11 @@ class OperationDashboard:          self.by_realisation_month = []          for fltr_key in self.filters_keys:              fltr, lbl = filters[fltr_key], filters_label[fltr_key] -            month_res = by_realisation_month.filter(**fltr)\ -                .annotate(number=Count('pk')).order_by('-date') +            month_res = ( +                by_realisation_month.filter(**fltr) +                .annotate(number=Count("pk")) +                .order_by("-date") +            )              month_dct = {}              for mt in month_res.all():                  month_dct[mt.date] = mt.number @@ -2864,151 +3219,161 @@ class OperationDashboard:          # survey and excavations          self.survey, self.excavation = {}, {} -        for dct_res, ope_types in ((self.survey, ('arch_diagnostic',)), -                                   (self.excavation, ('prev_excavation', -                                                      'prog_excavation'))): -            dct_res['total'] = [] -            operation_type = {'operation_type__txt_idx__in': ope_types} +        for dct_res, ope_types in ( +            (self.survey, ("arch_diagnostic",)), +            (self.excavation, ("prev_excavation", "prog_excavation")), +        ): +            dct_res["total"] = [] +            operation_type = {"operation_type__txt_idx__in": ope_types}              for fltr_key in self.filters_keys:                  fltr, lbl = filters[fltr_key], filters_label[fltr_key]                  fltr.update(operation_type)                  nb = Operation.objects.filter(**fltr).count() -                dct_res['total'].append((lbl, nb)) +                dct_res["total"].append((lbl, nb)) -            dct_res['by_year'] = [] +            dct_res["by_year"] = []              for fltr_key in self.filters_keys:                  fltr, lbl = filters[fltr_key], filters_label[fltr_key]                  fltr.update(operation_type) -                year_res = Operation.objects.filter(**fltr)\ -                                            .values('year')\ -                                            .annotate(number=Count('pk'))\ -                                            .order_by('year') +                year_res = ( +                    Operation.objects.filter(**fltr) +                    .values("year") +                    .annotate(number=Count("pk")) +                    .order_by("year") +                )                  years_dct = {}                  for yr in year_res.all(): -                    years_dct[yr['year']] = yr["number"] +                    years_dct[yr["year"]] = yr["number"]                  years = []                  for yr in self.years:                      if yr in years_dct:                          years.append(years_dct[yr])                      else:                          years.append(0) -                dct_res['by_year'].append((lbl, years)) +                dct_res["by_year"].append((lbl, years)) -            dct_res['by_realisation_year'] = [] +            dct_res["by_realisation_year"] = []              for fltr_key in self.filters_keys:                  fltr, lbl = filters[fltr_key], filters_label[fltr_key]                  fltr.update(operation_type) -                year_res = Operation.objects.filter(**fltr).extra( -                    {'date': "date_trunc('year', start_date)"})\ -                    .values('date')\ -                    .filter(start_date__isnull=False)\ -                    .annotate(number=Count('pk'))\ -                    .order_by('-date') +                year_res = ( +                    Operation.objects.filter(**fltr) +                    .extra({"date": "date_trunc('year', start_date)"}) +                    .values("date") +                    .filter(start_date__isnull=False) +                    .annotate(number=Count("pk")) +                    .order_by("-date") +                )                  years_dct = {}                  for yr in year_res.all(): -                    years_dct[yr['date']] = yr["number"] +                    years_dct[yr["date"]] = yr["number"]                  years = []                  for yr in self.realisation_years:                      if yr in years_dct:                          years.append(years_dct[yr])                      else:                          years.append(0) -                dct_res['by_realisation_year'].append((lbl, years)) - -            current_year_ope = Operation.objects.filter(**operation_type)\ -                                        .filter( -                                            year=datetime.date.today().year) -            current_realisation_year_ope = Operation.objects\ -                .filter(**operation_type)\ -                .filter(start_date__year=datetime.date.today().year) -            res_keys = [('area_realised', current_realisation_year_ope)] +                dct_res["by_realisation_year"].append((lbl, years)) + +            current_year_ope = Operation.objects.filter(**operation_type).filter( +                year=datetime.date.today().year +            ) +            current_realisation_year_ope = Operation.objects.filter( +                **operation_type +            ).filter(start_date__year=datetime.date.today().year) +            res_keys = [("area_realised", current_realisation_year_ope)]              if dct_res == self.survey: -                res_keys.append(('area', -                                 current_year_ope)) +                res_keys.append(("area", current_year_ope))              for res_key, base_ope in res_keys:                  dct_res[res_key] = []                  for fltr_key in self.filters_keys:                      fltr, lbl = filters[fltr_key], filters_label[fltr_key] -                    area_res = base_ope.filter(**fltr)\ -                        .annotate(number=Sum('surface')).all() +                    area_res = ( +                        base_ope.filter(**fltr).annotate(number=Sum("surface")).all() +                    )                      val = 0                      if area_res:                          val = (area_res[0].number or 0) / 10000.0                      dct_res[res_key].append(val)              # TODO... -            res_keys = [('manday_realised', current_realisation_year_ope)] +            res_keys = [("manday_realised", current_realisation_year_ope)]              if dct_res == self.survey: -                res_keys.append(('manday', -                                 current_year_ope)) +                res_keys.append(("manday", current_year_ope))              for res_key, base_ope in res_keys:                  dct_res[res_key] = []                  for fltr_key in self.filters_keys: -                    dct_res[res_key].append('-') +                    dct_res[res_key].append("-")              # TODO... -            res_keys = [('mandayhect_realised', current_realisation_year_ope)] +            res_keys = [("mandayhect_realised", current_realisation_year_ope)]              if dct_res == self.survey: -                res_keys.append(('mandayhect', -                                 current_year_ope)) +                res_keys.append(("mandayhect", current_year_ope))              for res_key, base_ope in res_keys:                  dct_res[res_key] = []                  for fltr_key in self.filters_keys: -                    dct_res[res_key].append('-') +                    dct_res[res_key].append("-")              # TODO... -            dct_res['mandayhect_real_effective'] = '-' +            dct_res["mandayhect_real_effective"] = "-"              if dct_res == self.survey: -                dct_res['mandayhect_effective'] = '-' +                dct_res["mandayhect_effective"] = "-" -            res_keys = [('org_realised', current_realisation_year_ope)] +            res_keys = [("org_realised", current_realisation_year_ope)]              if dct_res == self.survey: -                res_keys.append(('org', current_year_ope)) +                res_keys.append(("org", current_year_ope))              for res_key, base_ope in res_keys: -                org_res = base_ope.filter(scientist__attached_to__isnull=False)\ -                    .values('scientist__attached_to', -                            'scientist__attached_to__name')\ -                    .annotate(area=Sum('surface'))\ -                    .order_by('scientist__attached_to__name').all() +                org_res = ( +                    base_ope.filter(scientist__attached_to__isnull=False) +                    .values("scientist__attached_to", "scientist__attached_to__name") +                    .annotate(area=Sum("surface")) +                    .order_by("scientist__attached_to__name") +                    .all() +                )                  # TODO: man-days, man-days/hectare                  dct_res[res_key] = []                  for vals in org_res: -                    vals['area'] = (vals['area'] or 0) / 10000.0 +                    vals["area"] = (vals["area"] or 0) / 10000.0                      dct_res[res_key].append(vals)              year_ope = Operation.objects.filter(**operation_type) -            res_keys = ['org_by_year'] +            res_keys = ["org_by_year"]              if dct_res == self.survey: -                res_keys.append('org_by_year_realised') -            q = year_ope.values('scientist__attached_to', -                                'scientist__attached_to__name')\ -                .filter(scientist__attached_to__isnull=False)\ -                .order_by('scientist__attached_to__name').distinct() -            org_list = [(org['scientist__attached_to'], -                         org['scientist__attached_to__name']) for org in q] +                res_keys.append("org_by_year_realised") +            q = ( +                year_ope.values( +                    "scientist__attached_to", "scientist__attached_to__name" +                ) +                .filter(scientist__attached_to__isnull=False) +                .order_by("scientist__attached_to__name") +                .distinct() +            ) +            org_list = [ +                (org["scientist__attached_to"], org["scientist__attached_to__name"]) +                for org in q +            ]              # org_list_dct = dict(org_list)              for res_key in res_keys:                  dct_res[res_key] = []                  years = self.years -                if res_key == 'org_by_year_realised': +                if res_key == "org_by_year_realised":                      years = self.realisation_years                  for org_id, org_label in org_list: -                    org_res = year_ope.filter( -                        scientist__attached_to__pk=org_id) -                    key_date = '' -                    if res_key == 'org_by_year': -                        org_res = org_res.values('year') -                        key_date = 'year' +                    org_res = year_ope.filter(scientist__attached_to__pk=org_id) +                    key_date = "" +                    if res_key == "org_by_year": +                        org_res = org_res.values("year") +                        key_date = "year"                      else: -                        org_res = org_res\ -                            .extra({'date': "date_trunc('year', start_date)"})\ -                            .values('date')\ +                        org_res = ( +                            org_res.extra({"date": "date_trunc('year', start_date)"}) +                            .values("date")                              .filter(start_date__isnull=False) -                        key_date = 'date' -                    org_res = org_res.annotate(area=Sum('surface'), -                                               cost=Sum('cost')) +                        ) +                        key_date = "date" +                    org_res = org_res.annotate(area=Sum("surface"), cost=Sum("cost"))                      years_dct = {}                      for yr in org_res.all(): -                        area = (yr['area'] if yr['area'] else 0) / 10000.0 -                        cost = yr['cost'] if yr['cost'] else 0 +                        area = (yr["area"] if yr["area"] else 0) / 10000.0 +                        cost = yr["cost"] if yr["cost"] else 0                          years_dct[yr[key_date]] = (area, cost)                      r_years = []                      for yr in years: @@ -3029,35 +3394,37 @@ class OperationDashboard:                      area_sums.append(sum_area)                      cost_means.append(sum_cost / len(vals))                      cost_sums.append(sum_cost) -                dct_res[res_key + '_area_mean'] = area_means -                dct_res[res_key + '_area_sum'] = area_sums -                dct_res[res_key + '_cost_mean'] = cost_means -                dct_res[res_key + '_cost_mean'] = cost_sums +                dct_res[res_key + "_area_mean"] = area_means +                dct_res[res_key + "_area_sum"] = area_sums +                dct_res[res_key + "_cost_mean"] = cost_means +                dct_res[res_key + "_cost_mean"] = cost_sums              if dct_res == self.survey: -                self.survey['effective'] = [] +                self.survey["effective"] = []                  for yr in self.years: -                    year_res = Operation.objects\ -                        .filter(scientist__isnull=False, year=yr, -                                operation_type__txt_idx__in=ope_types)\ -                        .annotate(number=Sum('surface'), mean=Avg('surface')) +                    year_res = Operation.objects.filter( +                        scientist__isnull=False, +                        year=yr, +                        operation_type__txt_idx__in=ope_types, +                    ).annotate(number=Sum("surface"), mean=Avg("surface"))                      nb = year_res[0].number if year_res.count() else 0                      nb = nb if nb else 0                      mean = year_res[0].mean if year_res.count() else 0                      mean = mean if mean else 0 -                    self.survey['effective'].append((nb, mean)) +                    self.survey["effective"].append((nb, mean))              # TODO:Man-Days/hectare by Year              # CHECK: month of realisation or month? -            dct_res['by_month'] = [] +            dct_res["by_month"] = []              for fltr_key in self.filters_keys:                  fltr, lbl = filters[fltr_key], filters_label[fltr_key]                  fltr.update(operation_type) -                month_res = by_realisation_month\ -                    .filter(**fltr)\ -                    .annotate(number=Count('pk'))\ -                    .order_by('-date') +                month_res = ( +                    by_realisation_month.filter(**fltr) +                    .annotate(number=Count("pk")) +                    .order_by("-date") +                )                  month_dct = {}                  for mt in month_res.all():                      month_dct[mt.date] = mt.number @@ -3068,26 +3435,30 @@ class OperationDashboard:                          months.append(month_dct[date])                      else:                          months.append(0) -                dct_res['by_month'].append((lbl, months)) +                dct_res["by_month"].append((lbl, months)) -            operation_type = {'operation_type__txt_idx__in': ope_types} +            operation_type = {"operation_type__txt_idx__in": ope_types}              self.departments = [ -                (fd['department__pk'], fd['department__label']) -                for fd in OperationByDepartment -                .objects.filter(department__isnull=False) -                .values('department__label', 'department__pk') -                .order_by('department__label').distinct()] -            dct_res['by_dpt'] = [] +                (fd["department__pk"], fd["department__label"]) +                for fd in OperationByDepartment.objects.filter(department__isnull=False) +                .values("department__label", "department__pk") +                .order_by("department__label") +                .distinct() +            ] +            dct_res["by_dpt"] = []              for dpt_id, dpt_label in self.departments: -                vals = OperationByDepartment.objects\ -                    .filter(department__pk=dpt_id, -                            operation__operation_type__txt_idx__in=ope_types)\ -                    .values('department__pk', 'operation__year')\ -                    .annotate(number=Count('operation'))\ -                    .order_by('operation__year') +                vals = ( +                    OperationByDepartment.objects.filter( +                        department__pk=dpt_id, +                        operation__operation_type__txt_idx__in=ope_types, +                    ) +                    .values("department__pk", "operation__year") +                    .annotate(number=Count("operation")) +                    .order_by("operation__year") +                )                  dct_years = {}                  for v in vals: -                    dct_years[v['operation__year']] = v['number'] +                    dct_years[v["operation__year"]] = v["number"]                  years = []                  for y in self.years:                      if y in dct_years: @@ -3095,29 +3466,34 @@ class OperationDashboard:                      else:                          years.append(0)                  years.append(sum(years)) -                dct_res['by_dpt'].append((dpt_label, years)) -            dct_res['effective_by_dpt'] = [] +                dct_res["by_dpt"].append((dpt_label, years)) +            dct_res["effective_by_dpt"] = []              for dpt_id, dpt_label in self.departments: -                vals = OperationByDepartment.objects\ -                    .filter(department__pk=dpt_id, -                            operation__scientist__isnull=False, -                            operation__operation_type__txt_idx__in=ope_types)\ -                    .values('department__pk', 'operation__year')\ -                    .annotate(number=Count('operation'), -                              area=Sum('operation__surface'), -                              fnap=Sum('operation__fnap_cost'), -                              cost=Sum('operation__cost'))\ -                    .order_by('operation__year') +                vals = ( +                    OperationByDepartment.objects.filter( +                        department__pk=dpt_id, +                        operation__scientist__isnull=False, +                        operation__operation_type__txt_idx__in=ope_types, +                    ) +                    .values("department__pk", "operation__year") +                    .annotate( +                        number=Count("operation"), +                        area=Sum("operation__surface"), +                        fnap=Sum("operation__fnap_cost"), +                        cost=Sum("operation__cost"), +                    ) +                    .order_by("operation__year") +                )                  dct_years = {}                  for v in vals:                      values = [] -                    for k in ('number', 'area', 'cost', 'fnap'): +                    for k in ("number", "area", "cost", "fnap"):                          value = v[k] or 0 -                        if k == 'area': +                        if k == "area":                              value /= 10000.0                          values.append(value) -                    dct_years[v['operation__year']] = values +                    dct_years[v["operation__year"]] = values                  years = []                  for y in self.years:                      if y in dct_years: @@ -3126,47 +3502,67 @@ class OperationDashboard:                          years.append((0, 0, 0, 0))                  nbs, areas, costs, fnaps = zip(*years)                  years.append((sum(nbs), sum(areas), sum(costs), sum(fnaps))) -                dct_res['effective_by_dpt'].append((dpt_label, years)) +                dct_res["effective_by_dpt"].append((dpt_label, years))              OperationTown = Operation.towns.through -            query = OperationTown.objects\ -                .filter(operation__scientist__isnull=False, -                        operation__operation_type__txt_idx__in=ope_types)\ -                .values('town__name', 'town__departement__number')\ -                .annotate(nb=Count('operation'))\ -                .order_by('-nb', 'town__name')[:10] -            dct_res['towns'] = [] +            query = ( +                OperationTown.objects.filter( +                    operation__scientist__isnull=False, +                    operation__operation_type__txt_idx__in=ope_types, +                ) +                .values("town__name", "town__departement__number") +                .annotate(nb=Count("operation")) +                .order_by("-nb", "town__name")[:10] +            ) +            dct_res["towns"] = []              for r in query: -                dct_res['towns'].append(("%s (%s)" % (r['town__name'], -                                         r['town__departement__number']), -                                         r['nb'])) +                dct_res["towns"].append( +                    ( +                        "%s (%s)" % (r["town__name"], r["town__departement__number"]), +                        r["nb"], +                    ) +                )              if dct_res == self.survey: -                query = OperationTown.objects\ -                    .filter(operation__scientist__isnull=False, -                            operation__operation_type__txt_idx__in=ope_types, -                            operation__surface__isnull=False)\ -                    .values('town__name', 'town__departement__number')\ -                    .annotate(nb=Sum('operation__surface'))\ -                    .order_by('-nb', 'town__name')[:10] -                dct_res['towns_surface'] = [] +                query = ( +                    OperationTown.objects.filter( +                        operation__scientist__isnull=False, +                        operation__operation_type__txt_idx__in=ope_types, +                        operation__surface__isnull=False, +                    ) +                    .values("town__name", "town__departement__number") +                    .annotate(nb=Sum("operation__surface")) +                    .order_by("-nb", "town__name")[:10] +                ) +                dct_res["towns_surface"] = []                  for r in query: -                    dct_res['towns_surface'].append(("%s (%s)" % ( -                        r['town__name'], r['town__departement__number']), -                        r['nb'])) +                    dct_res["towns_surface"].append( +                        ( +                            "%s (%s)" +                            % (r["town__name"], r["town__departement__number"]), +                            r["nb"], +                        ) +                    )              else: -                query = OperationTown.objects\ -                    .filter(operation__scientist__isnull=False, -                            operation__operation_type__txt_idx__in=ope_types, -                            operation__cost__isnull=False)\ -                    .values('town__name', 'town__departement__number')\ -                    .annotate(nb=Sum('operation__cost'))\ -                    .order_by('-nb', 'town__name')[:10] -                dct_res['towns_cost'] = [] +                query = ( +                    OperationTown.objects.filter( +                        operation__scientist__isnull=False, +                        operation__operation_type__txt_idx__in=ope_types, +                        operation__cost__isnull=False, +                    ) +                    .values("town__name", "town__departement__number") +                    .annotate(nb=Sum("operation__cost")) +                    .order_by("-nb", "town__name")[:10] +                ) +                dct_res["towns_cost"] = []                  for r in query: -                    dct_res['towns_cost'].append(("%s (%s)" % ( -                        r['town__name'], r['town__departement__number']), -                        r['nb'])) +                    dct_res["towns_cost"].append( +                        ( +                            "%s (%s)" +                            % (r["town__name"], r["town__departement__number"]), +                            r["nb"], +                        ) +                    )  class OperationTypeOld(GeneralType): @@ -3176,4 +3572,4 @@ class OperationTypeOld(GeneralType):      class Meta:          verbose_name = _("Operation type old")          verbose_name_plural = _("Operation types old") -        ordering = ['-preventive', 'order', 'label'] +        ordering = ["-preventive", "order", "label"] | 
