diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-03-19 11:21:04 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-03-19 11:21:04 +0100 |
commit | ced270d071384046eb3b9a85572dc817c7ef042c (patch) | |
tree | 1696a72b2ec46fa34981533484e0d67ec9d14e93 | |
parent | baf29e1bb4b18fb9830956c53f3475db2f828e3f (diff) | |
download | Ishtar-ced270d071384046eb3b9a85572dc817c7ef042c.tar.bz2 Ishtar-ced270d071384046eb3b9a85572dc817c7ef042c.zip |
Format - black: operation
-rw-r--r-- | archaeological_operations/ishtar_menu.py | 222 | ||||
-rw-r--r-- | archaeological_operations/lookups.py | 55 | ||||
-rw-r--r-- | archaeological_operations/models.py | 2974 | ||||
-rw-r--r-- | archaeological_operations/serializers.py | 162 | ||||
-rw-r--r-- | archaeological_operations/tests.py | 3004 | ||||
-rw-r--r-- | archaeological_operations/urls.py | 501 | ||||
-rw-r--r-- | archaeological_operations/utils.py | 241 | ||||
-rw-r--r-- | archaeological_operations/views.py | 864 | ||||
-rw-r--r-- | archaeological_operations/widgets.py | 29 | ||||
-rw-r--r-- | archaeological_operations/wizards.py | 336 |
10 files changed, 4824 insertions, 3564 deletions
diff --git a/archaeological_operations/ishtar_menu.py b/archaeological_operations/ishtar_menu.py index 6a5ae1d46..2ad6dc259 100644 --- a/archaeological_operations/ishtar_menu.py +++ b/archaeological_operations/ishtar_menu.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2012-2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -28,102 +28,140 @@ from archaeological_operations import models MENU_SECTIONS = [ - (30, SectionItem( - 'operation_management', _("Operation"), - css='menu-operation', - childs=[ - MenuItem( - 'operation_search', _("Search"), - model=models.Operation, - access_controls=['view_operation', - 'view_own_operation']), - MenuItem( - 'operation_creation', _("Creation"), - model=models.Operation, - access_controls=['add_operation', - 'add_own_operation']), - MenuItem( - 'operation_modification', _("Modification"), - model=models.Operation, - access_controls=['change_operation', - 'change_own_operation']), - MenuItem( - 'operation_closing', _("Closing"), - model=models.Operation, - access_controls=['close_operation']), - MenuItem( - 'operation_deletion', _("Deletion"), - model=models.Operation, - access_controls=['change_operation', - 'change_own_operation']), - SectionItem( - 'admin_act_operations', - _("Administrative act"), - profile_restriction='files', - childs=[ - MenuItem( - 'operation_administrativeactop_search', - _("Search"), - model=models.AdministrativeAct, - access_controls=[ - 'change_administrativeact']), - MenuItem( - 'operation_administrativeactop', - _("Creation"), - model=models.AdministrativeAct, - access_controls=['change_administrativeact']), - MenuItem( - 'operation_administrativeactop_modification', - _("Modification"), - model=models.AdministrativeAct, - access_controls=['change_administrativeact']), - MenuItem( - 'operation_administrativeactop_deletion', - _("Deletion"), - model=models.AdministrativeAct, - access_controls=['change_administrativeact']), - ],), - ]), - ), ( - 35, SectionItem( - 'administrativact_management', _("Administrative Act"), - profile_restriction='files', - css='menu-file', + 30, + SectionItem( + "operation_management", + _("Operation"), + css="menu-operation", childs=[ MenuItem( - 'administrativact_register', - pgettext_lazy('admin act register', "Register"), + "operation_search", + _("Search"), + model=models.Operation, + access_controls=["view_operation", "view_own_operation"], + ), + MenuItem( + "operation_creation", + _("Creation"), + model=models.Operation, + access_controls=["add_operation", "add_own_operation"], + ), + MenuItem( + "operation_modification", + _("Modification"), + model=models.Operation, + access_controls=["change_operation", "change_own_operation"], + ), + MenuItem( + "operation_closing", + _("Closing"), + model=models.Operation, + access_controls=["close_operation"], + ), + MenuItem( + "operation_deletion", + _("Deletion"), + model=models.Operation, + access_controls=["change_operation", "change_own_operation"], + ), + SectionItem( + "admin_act_operations", + _("Administrative act"), + profile_restriction="files", + childs=[ + MenuItem( + "operation_administrativeactop_search", + _("Search"), + model=models.AdministrativeAct, + access_controls=["change_administrativeact"], + ), + MenuItem( + "operation_administrativeactop", + _("Creation"), + model=models.AdministrativeAct, + access_controls=["change_administrativeact"], + ), + MenuItem( + "operation_administrativeactop_modification", + _("Modification"), + model=models.AdministrativeAct, + access_controls=["change_administrativeact"], + ), + MenuItem( + "operation_administrativeactop_deletion", + _("Deletion"), + model=models.AdministrativeAct, + access_controls=["change_administrativeact"], + ), + ], + ), + ], + ), + ), + ( + 35, + SectionItem( + "administrativact_management", + _("Administrative Act"), + profile_restriction="files", + css="menu-file", + childs=[ + MenuItem( + "administrativact_register", + pgettext_lazy("admin act register", "Register"), model=models.AdministrativeAct, - access_controls=['view_administrativeact', - 'view_own_administrativeact']), - ]) + access_controls=[ + "view_administrativeact", + "view_own_administrativeact", + ], + ), + ], + ), ), - (37, SectionItem( - 'site_management', IshtarSiteProfile.get_default_site_label, - css='menu-site', - profile_restriction='archaeological_site', - childs=[ - MenuItem( - 'site_search', _("Search"), - model=models.ArchaeologicalSite, - access_controls=['view_archaeologicalsite', - 'view_own_archaeologicalsite']), - MenuItem( - 'site_creation', _("Creation"), - model=models.ArchaeologicalSite, - access_controls=['add_archaeologicalsite', - 'add_own_archaeologicalsite']), - MenuItem( - 'site_modification', _("Modification"), - model=models.ArchaeologicalSite, - access_controls=['change_archaeologicalsite', - 'change_own_archaeologicalsite']), - MenuItem('site_deletion', - _("Deletion"), - model=models.ArchaeologicalSite, - access_controls=['change_archaeologicalsite']), - ]), + ( + 37, + SectionItem( + "site_management", + IshtarSiteProfile.get_default_site_label, + css="menu-site", + profile_restriction="archaeological_site", + childs=[ + MenuItem( + "site_search", + _("Search"), + model=models.ArchaeologicalSite, + access_controls=[ + "view_archaeologicalsite", + "view_own_archaeologicalsite", + ], + ), + MenuItem( + "site_creation", + _("Creation"), + model=models.ArchaeologicalSite, + access_controls=[ + "add_archaeologicalsite", + "add_own_archaeologicalsite", + ], + ), + MenuItem( + "site_modification", + _("Modification"), + model=models.ArchaeologicalSite, + access_controls=[ + "change_archaeologicalsite", + "change_own_archaeologicalsite", + ], + ), + MenuItem( + "site_deletion", + _("Deletion"), + model=models.ArchaeologicalSite, + access_controls=["change_archaeologicalsite"], + ), + ], + ), ), ] """ diff --git a/archaeological_operations/lookups.py b/archaeological_operations/lookups.py index 66bcf0831..0b590374e 100644 --- a/archaeological_operations/lookups.py +++ b/archaeological_operations/lookups.py @@ -6,70 +6,69 @@ from django.db.models import Q from django.utils.encoding import force_text from django.utils.html import escape -from archaeological_operations.models import Operation, ArchaeologicalSite, \ - Parcel, CulturalAttributionType +from archaeological_operations.models import ( + Operation, + ArchaeologicalSite, + Parcel, + CulturalAttributionType, +) -@register('operation') +@register("operation") class OperationLookup(LookupChannel): model = Operation def get_query(self, q, request): query = Q() - for term in q.strip().split(' '): - subquery = ( - Q(cached_label__icontains=term) - ) + for term in q.strip().split(" "): + subquery = Q(cached_label__icontains=term) query &= subquery - return self.model.objects.filter(query).order_by('cached_label')[:20] + return self.model.objects.filter(query).order_by("cached_label")[:20] def format_item_display(self, item): return "<span class='ajax-label'>%s</span>" % item.cached_label -@register('archaeological_site') +@register("archaeological_site") class ArchaeologicalSiteLookup(LookupChannel): model = ArchaeologicalSite def get_query(self, q, request): query = Q() - for term in q.strip().split(' '): - subquery = ( - Q(reference__icontains=term) | - Q(name__icontains=term) - ) + for term in q.strip().split(" "): + subquery = Q(reference__icontains=term) | Q(name__icontains=term) query &= subquery - return self.model.objects.filter(query).order_by('reference', - 'name')[:20] + return self.model.objects.filter(query).order_by("reference", "name")[:20] def format_item_display(self, item): return "<span class='ajax-label'>%s</span>".format(item) -@register('parcel') +@register("parcel") class ParcelLookup(LookupChannel): model = Parcel def get_query(self, q, request): query = Q() - for term in q.strip().split(' '): + for term in q.strip().split(" "): subquery = ( - Q(associated_file__cached_label__icontains=term) | - Q(operation__cached_label__icontains=term) | - Q(section__icontains=term) | - Q(parcel_number__icontains=term) | - Q(town__name__icontains=term) + Q(associated_file__cached_label__icontains=term) + | Q(operation__cached_label__icontains=term) + | Q(section__icontains=term) + | Q(parcel_number__icontains=term) + | Q(town__name__icontains=term) ) try: subquery |= Q(year=int(term)) except ValueError: pass query &= subquery - return self.model.objects.filter( - query).order_by('-associated_file__cached_label', - '-operation__cached_label', - 'section', - 'parcel_number')[:20] + return self.model.objects.filter(query).order_by( + "-associated_file__cached_label", + "-operation__cached_label", + "section", + "parcel_number", + )[:20] def format_match(self, obj): return escape(force_text(obj.long_label())) 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"] diff --git a/archaeological_operations/serializers.py b/archaeological_operations/serializers.py index 91b0b1b0f..5fee27a4e 100644 --- a/archaeological_operations/serializers.py +++ b/archaeological_operations/serializers.py @@ -1,13 +1,15 @@ from django.db.models import Q -from ishtar_common.serializers_utils import generic_get_results, \ - archive_serialization +from ishtar_common.serializers_utils import generic_get_results, archive_serialization from archaeological_operations import models OPERATION_MODEL_LIST = [ - models.ArchaeologicalSite, models.Operation, models.RecordRelations, - models.Parcel, models.ParcelOwner + models.ArchaeologicalSite, + models.Operation, + models.RecordRelations, + models.Parcel, + models.ParcelOwner, ] # TODO: administrativ acts, associated documents @@ -20,17 +22,30 @@ def generate_warehouse_queryset(ids): for container_key in ("container", "container_ref"): for warehouse_key in ("location", "responsible"): - q_s = Q(** - {"operations__{}__{}__{}__id__in".format( - base_query_key, container_key, warehouse_key): ids}) - q_o = Q(** - {"{}__{}__{}__id__in".format( - base_query_key, container_key, warehouse_key): ids}) - q_r = Q(** - {"left_record__{}__{}__{}__id__in".format( - base_query_key, container_key, warehouse_key): ids, - "right_record__{}__{}__{}__id__in".format( - base_query_key, container_key, warehouse_key): ids}) + q_s = Q( + **{ + "operations__{}__{}__{}__id__in".format( + base_query_key, container_key, warehouse_key + ): ids + } + ) + q_o = Q( + **{ + "{}__{}__{}__id__in".format( + base_query_key, container_key, warehouse_key + ): ids + } + ) + q_r = Q( + **{ + "left_record__{}__{}__{}__id__in".format( + base_query_key, container_key, warehouse_key + ): ids, + "right_record__{}__{}__{}__id__in".format( + base_query_key, container_key, warehouse_key + ): ids, + } + ) if not q_archaeological_site: q_archaeological_site = q_s q_operation = q_o @@ -41,81 +56,83 @@ def generate_warehouse_queryset(ids): q_record_relation |= q_r result_queryset = { - models.ArchaeologicalSite.__name__: - models.ArchaeologicalSite.objects.filter( - q_archaeological_site - ), - models.Operation.__name__: models.Operation.objects.filter( - q_operation), - models.RecordRelations.__name__: - models.RecordRelations.objects.filter(q_record_relation), + models.ArchaeologicalSite.__name__: models.ArchaeologicalSite.objects.filter( + q_archaeological_site + ), + models.Operation.__name__: models.Operation.objects.filter(q_operation), + models.RecordRelations.__name__: models.RecordRelations.objects.filter( + q_record_relation + ), } return result_queryset -def operation_serialization(archive=False, return_empty_types=False, - archive_name=None, operation_queryset=None, - site_queryset=None, cr_queryset=None, - find_queryset=None, warehouse_queryset=None, - get_queryset=False, no_geo=True, - put_locks=False, lock_user=None): +def operation_serialization( + archive=False, + return_empty_types=False, + archive_name=None, + operation_queryset=None, + site_queryset=None, + cr_queryset=None, + find_queryset=None, + warehouse_queryset=None, + get_queryset=False, + no_geo=True, + put_locks=False, + lock_user=None, +): result_queryset = {} if operation_queryset: operation_ids = operation_queryset.values_list("id", flat=True) result_queryset = { models.Operation.__name__: operation_queryset, - models.RecordRelations.__name__: - models.RecordRelations.objects.filter( - left_record__id__in=operation_ids, - right_record__id__in=operation_ids, - ), - models.ArchaeologicalSite.__name__: - models.ArchaeologicalSite.objects.filter( - operations__id__in=operation_ids - ) + models.RecordRelations.__name__: models.RecordRelations.objects.filter( + left_record__id__in=operation_ids, + right_record__id__in=operation_ids, + ), + models.ArchaeologicalSite.__name__: models.ArchaeologicalSite.objects.filter( + operations__id__in=operation_ids + ), } elif site_queryset: site_ids = site_queryset.values_list("id", flat=True) result_queryset = { models.ArchaeologicalSite.__name__: site_queryset, models.Operation.__name__: models.Operation.objects.filter( - archaeological_sites__id__in=site_ids), - models.RecordRelations.__name__: - models.RecordRelations.objects.filter( - left_record__archaeological_sites__id__in=site_ids, - right_record__archaeological_sites__id__in=site_ids, - ), + archaeological_sites__id__in=site_ids + ), + models.RecordRelations.__name__: models.RecordRelations.objects.filter( + left_record__archaeological_sites__id__in=site_ids, + right_record__archaeological_sites__id__in=site_ids, + ), } elif cr_queryset: cr_ids = cr_queryset.values_list("id", flat=True) result_queryset = { - models.ArchaeologicalSite.__name__: - models.ArchaeologicalSite.objects.filter( - operations__context_record__id__in=cr_ids), + models.ArchaeologicalSite.__name__: models.ArchaeologicalSite.objects.filter( + operations__context_record__id__in=cr_ids + ), models.Operation.__name__: models.Operation.objects.filter( - context_record__id__in=cr_ids), - models.RecordRelations.__name__: - models.RecordRelations.objects.filter( - left_record__context_record__id__in=cr_ids, - right_record__context_record__id__in=cr_ids, - ), + context_record__id__in=cr_ids + ), + models.RecordRelations.__name__: models.RecordRelations.objects.filter( + left_record__context_record__id__in=cr_ids, + right_record__context_record__id__in=cr_ids, + ), } elif find_queryset: find_ids = find_queryset.values_list("id", flat=True) result_queryset = { - models.ArchaeologicalSite.__name__: - models.ArchaeologicalSite.objects.filter( - operations__context_record__base_finds__find__id__in - =find_ids), + models.ArchaeologicalSite.__name__: models.ArchaeologicalSite.objects.filter( + operations__context_record__base_finds__find__id__in=find_ids + ), models.Operation.__name__: models.Operation.objects.filter( - context_record__base_finds__find__id__in=find_ids), - models.RecordRelations.__name__: - models.RecordRelations.objects.filter( - left_record__context_record__base_finds__find__id__in= - find_ids, - right_record__context_record__base_finds__find__id__in= - find_ids, - ), + context_record__base_finds__find__id__in=find_ids + ), + models.RecordRelations.__name__: models.RecordRelations.objects.filter( + left_record__context_record__base_finds__find__id__in=find_ids, + right_record__context_record__base_finds__find__id__in=find_ids, + ), } elif warehouse_queryset: warehouse_ids = warehouse_queryset.values_list("id", flat=True) @@ -123,8 +140,12 @@ def operation_serialization(archive=False, return_empty_types=False, if get_queryset: return result_queryset - result = generic_get_results(OPERATION_MODEL_LIST, "operations", - result_queryset=result_queryset, no_geo=no_geo) + result = generic_get_results( + OPERATION_MODEL_LIST, + "operations", + result_queryset=result_queryset, + no_geo=no_geo, + ) if put_locks: for model in OPERATION_MODEL_LIST: @@ -136,7 +157,10 @@ def operation_serialization(archive=False, return_empty_types=False, q.update(locked=True, lock_user=lock_user) full_archive = archive_serialization( - result, archive_dir="operations", archive=archive, - return_empty_types=return_empty_types, archive_name=archive_name, + result, + archive_dir="operations", + archive=archive, + return_empty_types=return_empty_types, + archive_name=archive_name, ) return full_archive diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 1e85b4f5a..3f4e73639 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2012-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -42,55 +42,102 @@ from ishtar_common.views import document_deletion_steps from ishtar_common.serializers import document_serialization from archaeological_operations import views, serializers -from ishtar_common.models import OrganizationType, Organization, ItemKey, \ - ImporterType, IshtarUser, TargetKey, ImporterModel, IshtarSiteProfile, \ - Town, ImporterColumn, Person, Author, SourceType, AuthorType, \ - DocumentTemplate, PersonType, TargetKeyGroup, JsonDataField, \ - JsonDataSection, ImportTarget, FormaterType, CustomForm, ExcludedField, \ - UserProfile, ProfileType, Area, CustomFormJsonField, get_current_profile, \ - Document, ValueFormater, Regexp +from ishtar_common.models import ( + OrganizationType, + Organization, + ItemKey, + ImporterType, + IshtarUser, + TargetKey, + ImporterModel, + IshtarSiteProfile, + Town, + ImporterColumn, + Person, + Author, + SourceType, + AuthorType, + DocumentTemplate, + PersonType, + TargetKeyGroup, + JsonDataField, + JsonDataSection, + ImportTarget, + FormaterType, + CustomForm, + ExcludedField, + UserProfile, + ProfileType, + Area, + CustomFormJsonField, + get_current_profile, + Document, + ValueFormater, + Regexp, +) from archaeological_files.models import File, FileType from archaeological_context_records.models import Unit, ContextRecord from ishtar_common import forms_common -from ishtar_common.tests import WizardTest, WizardTestFormData as FormData, \ - create_superuser, create_user, TestCase, OPERATION_FIXTURES, \ - AutocompleteTestBase, AcItem, OPERATION_TOWNS_FIXTURES, FILE_FIXTURES, \ - COMMON_FIXTURES, GenericSerializationTest, WAREHOUSE_FIXTURES, SearchText +from ishtar_common.tests import ( + WizardTest, + WizardTestFormData as FormData, + create_superuser, + create_user, + TestCase, + OPERATION_FIXTURES, + AutocompleteTestBase, + AcItem, + OPERATION_TOWNS_FIXTURES, + FILE_FIXTURES, + COMMON_FIXTURES, + GenericSerializationTest, + WAREHOUSE_FIXTURES, + SearchText, +) from ishtar_common.serializers import restore_serialized class FileInit(object): def login_as_superuser(self): - self.client.login(username='username', password='tralala') + self.client.login(username="username", password="tralala") def create_file(self): self.extra_models, self.model_list = {}, [] - self.user, created = User.objects.get_or_create(username='username', - is_superuser=True) - self.user.set_password('tralala') + self.user, created = User.objects.get_or_create( + username="username", is_superuser=True + ) + self.user.set_password("tralala") self.user.save() - self.o_user, created = User.objects.get_or_create(username='ousername') + self.o_user, created = User.objects.get_or_create(username="ousername") person_type, created = PersonType.objects.get_or_create( - label='Test person type', txt_idx='test_person', - available=True) - self.extra_models['person_type'] = person_type + label="Test person type", txt_idx="test_person", available=True + ) + self.extra_models["person_type"] = person_type self.model_list.append(person_type) - person = models.Person(surname='Surname', name='Name', - history_modifier=self.o_user) + person = models.Person( + surname="Surname", name="Name", history_modifier=self.o_user + ) person.save() - self.extra_models['person'] = person + self.extra_models["person"] = person self.model_list.append(person) file_type, created = FileType.objects.get_or_create( - label='Test file type', txt_idx='test_file', available=True) - self.extra_models['file_type'] = file_type + label="Test file type", txt_idx="test_file", available=True + ) + self.extra_models["file_type"] = file_type self.model_list.append(file_type) - dct = {'year': 2010, 'numeric_reference': 1000, 'file_type': file_type, - 'internal_reference': 'UNIT_testÉ ?', 'in_charge': person, - 'history_modifier': self.o_user, 'total_surface': 10000} + dct = { + "year": 2010, + "numeric_reference": 1000, + "file_type": file_type, + "internal_reference": "UNIT_testÉ ?", + "in_charge": person, + "history_modifier": self.o_user, + "total_surface": 10000, + } self.item = File(**dct) self.item.save() @@ -101,29 +148,36 @@ class ImportTest(object): self.ishtar_user = IshtarUser.objects.get(pk=self.user.pk) def set_target_key(self, target, key, value, imp=None): - keys = {'target__target': target, 'key': key} + keys = {"target__target": target, "key": key} if imp: - keys['associated_import'] = imp + keys["associated_import"] = imp tg = TargetKey.objects.get(**keys) tg.value = value tg.is_set = True tg.save() - def init_ope_import(self, filename='MCC-operations-example.csv', - sep=","): + def init_ope_import(self, filename="MCC-operations-example.csv", sep=","): mcc_operation = ImporterType.objects.get(name="MCC - Opérations") mcc_operation_file = open( - settings.ROOT_PATH + - '../archaeological_operations/tests/' + filename, - 'rb') - file_dict = {'imported_file': SimpleUploadedFile( - mcc_operation_file.name, mcc_operation_file.read())} + settings.ROOT_PATH + "../archaeological_operations/tests/" + filename, "rb" + ) + file_dict = { + "imported_file": SimpleUploadedFile( + mcc_operation_file.name, mcc_operation_file.read() + ) + } group, c = TargetKeyGroup.objects.get_or_create(name="My group") - post_dict = {'importer_type': mcc_operation.pk, 'skip_lines': 1, - "encoding": 'utf-8', "name": 'init_ope_import', - "associated_group": group.pk, "csv_sep": sep} - form = forms_common.NewImportForm(data=post_dict, files=file_dict, - user=self.user) + post_dict = { + "importer_type": mcc_operation.pk, + "skip_lines": 1, + "encoding": "utf-8", + "name": "init_ope_import", + "associated_group": group.pk, + "csv_sep": sep, + } + form = forms_common.NewImportForm( + data=post_dict, files=file_dict, user=self.user + ) form.is_valid() return mcc_operation, form @@ -136,20 +190,22 @@ class ImportTest(object): ik.delete() # target for this import - target = TargetKey.objects.filter( - target__target='operation_type').order_by('-pk').all()[0] - target.value = models.OperationType.objects.get( - txt_idx='prog_excavation').pk + target = ( + TargetKey.objects.filter(target__target="operation_type") + .order_by("-pk") + .all()[0] + ) + target.value = models.OperationType.objects.get(txt_idx="prog_excavation").pk target.is_set = True target.associated_import = imp target.save() # target for all users - tgs = list(TargetKey.objects.filter(key='gallo-romain').all()) + tgs = list(TargetKey.objects.filter(key="gallo-romain").all()) for tg in tgs[1:]: tg.delete() target2 = tgs[0] - gallo = models.Period.objects.get(txt_idx='gallo-roman') + gallo = models.Period.objects.get(txt_idx="gallo-roman") target2.value = gallo.pk target2.is_set = True target2.associated_import = None @@ -158,11 +214,11 @@ class ImportTest(object): target2.save() # target for this user - tgs = list(TargetKey.objects.filter(key='age-du-fer').all()) + tgs = list(TargetKey.objects.filter(key="age-du-fer").all()) for tg in tgs[1:]: tg.delete() target3 = tgs[0] - iron = models.Period.objects.get(txt_idx='iron-age') + iron = models.Period.objects.get(txt_idx="iron-age") target3.value = iron.pk target3.is_set = True target3.associated_import = None @@ -173,11 +229,11 @@ class ImportTest(object): # target for another user username, password, user = create_user() another_user = IshtarUser.objects.get(pk=user.pk) - tgs = list(TargetKey.objects.filter(key='neolithik').all()) + tgs = list(TargetKey.objects.filter(key="neolithik").all()) for tg in tgs[1:]: tg.delete() target4 = tgs[0] - neo = models.Period.objects.get(txt_idx='neolithic') + neo = models.Period.objects.get(txt_idx="neolithic") target4.value = neo.pk target4.is_set = True target4.associated_import = None @@ -186,11 +242,11 @@ class ImportTest(object): target4.save() # target for the current group - tgs = list(TargetKey.objects.filter(key='moderne').all()) + tgs = list(TargetKey.objects.filter(key="moderne").all()) for tg in tgs[1:]: tg.delete() target5 = tgs[0] - modern = models.Period.objects.get(txt_idx='modern') + modern = models.Period.objects.get(txt_idx="modern") target5.value = modern.pk target5.is_set = True target5.associated_import = None @@ -211,16 +267,23 @@ class ImportTest(object): self.init_ope() mcc_parcel = ImporterType.objects.get(name="MCC - Parcelles") mcc_file = open( - settings.ROOT_PATH + - '../archaeological_operations/tests/MCC-parcelles-example.csv', - 'rb') - file_dict = {'imported_file': SimpleUploadedFile(mcc_file.name, - mcc_file.read())} - post_dict = {'importer_type': mcc_parcel.pk, 'skip_lines': 1, - "encoding": 'utf-8', "name": 'init_parcel_import', - "csv_sep": ","} - form = forms_common.NewImportForm(data=post_dict, files=file_dict, - user=self.user) + settings.ROOT_PATH + + "../archaeological_operations/tests/MCC-parcelles-example.csv", + "rb", + ) + file_dict = { + "imported_file": SimpleUploadedFile(mcc_file.name, mcc_file.read()) + } + post_dict = { + "importer_type": mcc_parcel.pk, + "skip_lines": 1, + "encoding": "utf-8", + "name": "init_parcel_import", + "csv_sep": ",", + } + form = forms_common.NewImportForm( + data=post_dict, files=file_dict, user=self.user + ) form.is_valid() return mcc_parcel, form @@ -234,25 +297,32 @@ class ImportTest(object): self.init_parcel() mcc = ImporterType.objects.get(name="MCC - UE") mcc_file = open( - settings.ROOT_PATH + - '../archaeological_context_records/tests/' - 'MCC-context-records-example.csv', 'rb') - file_dict = {'imported_file': SimpleUploadedFile(mcc_file.name, - mcc_file.read())} - post_dict = {'importer_type': mcc.pk, 'skip_lines': 1, - "encoding": 'utf-8', "name": 'init_context_record_import', - 'csv_sep': ","} - form = forms_common.NewImportForm(data=post_dict, files=file_dict, - user=self.user) + settings.ROOT_PATH + "../archaeological_context_records/tests/" + "MCC-context-records-example.csv", + "rb", + ) + file_dict = { + "imported_file": SimpleUploadedFile(mcc_file.name, mcc_file.read()) + } + post_dict = { + "importer_type": mcc.pk, + "skip_lines": 1, + "encoding": "utf-8", + "name": "init_context_record_import", + "csv_sep": ",", + } + form = forms_common.NewImportForm( + data=post_dict, files=file_dict, user=self.user + ) form.is_valid() return mcc, form def init_cr_targetkey(self, imp): - hc = Unit.objects.get(txt_idx='not_in_context').pk - self.set_target_key('unit', 'hc', hc, imp=imp) - self.set_target_key('unit', 'hors-contexte', hc, imp=imp) - layer = Unit.objects.get(txt_idx='negative').pk - self.set_target_key('unit', 'couche', layer, imp=imp) + hc = Unit.objects.get(txt_idx="not_in_context").pk + self.set_target_key("unit", "hc", hc, imp=imp) + self.set_target_key("unit", "hors-contexte", hc, imp=imp) + layer = Unit.objects.get(txt_idx="negative").pk + self.set_target_key("unit", "couche", layer, imp=imp) def init_context_record(self): mcc, form = self.init_context_record_import() @@ -294,31 +364,31 @@ class ImportOperationTest(ImportTest, TestCase): current_person_nb = Person.objects.count() self.assertEqual(current_person_nb, first_person_nb + 1) # and well imported - last_ope = models.Operation.objects.order_by('-pk').all()[0] + last_ope = models.Operation.objects.order_by("-pk").all()[0] self.assertEqual(last_ope.name, "Oppìdum de Paris") - self.assertEqual(last_ope.code_patriarche, '4200') - self.assertEqual(last_ope.operation_type.txt_idx, 'prog_excavation') + self.assertEqual(last_ope.code_patriarche, "4200") + self.assertEqual(last_ope.operation_type.txt_idx, "prog_excavation") self.assertEqual(last_ope.periods.count(), 3) periods = [period.txt_idx for period in last_ope.periods.all()] - self.assertIn('iron-age', periods) - self.assertIn('gallo-roman', periods) + self.assertIn("iron-age", periods) + self.assertIn("gallo-roman", periods) # target key set for another user - self.assertNotIn('neolithic', periods) + self.assertNotIn("neolithic", periods) # a second importation will be not possible: no two same patriarche # code impt.importation() - self.assertEqual(last_ope, - models.Operation.objects.order_by('-pk').all()[0]) + self.assertEqual(last_ope, models.Operation.objects.order_by("-pk").all()[0]) def test_import_bad_encoding(self): - self.init_ope_import('MCC-operations-example-bad-encoding.csv') + self.init_ope_import("MCC-operations-example-bad-encoding.csv") def test_import_semi_colon_sep(self): first_ope_nb = models.Operation.objects.count() importer, form = self.init_ope_import( - 'MCC-operations-example-semi-colon.csv', sep=";") + "MCC-operations-example-semi-colon.csv", sep=";" + ) self.assertTrue(form.is_valid()) impt = form.save(self.ishtar_user) impt.initialize() @@ -331,18 +401,22 @@ class ImportOperationTest(ImportTest, TestCase): def test_import_multi_column_concat(self): first_ope_nb = models.Operation.objects.count() importer, form = self.init_ope_import( - 'MCC-operations-example-multi-col-periods.csv') - col = ImporterColumn.objects.create(col_number=12, - importer_type_id=importer.pk) + "MCC-operations-example-multi-col-periods.csv" + ) + col = ImporterColumn.objects.create(col_number=12, importer_type_id=importer.pk) period_imp = ImporterColumn.objects.get( - col_number=9, - importer_type_id=importer.pk) + col_number=9, importer_type_id=importer.pk + ) period_target = period_imp.targets.all()[0] target = ImportTarget.objects.create( - column=col, target=period_target.target, - formater_type=period_target.formater_type, concat=True) + column=col, + target=period_target.target, + formater_type=period_target.formater_type, + concat=True, + ) importer, form = self.init_ope_import( - 'MCC-operations-example-multi-col-periods.csv') + "MCC-operations-example-multi-col-periods.csv" + ) self.assertTrue(form.is_valid()) impt = form.save(self.ishtar_user) @@ -352,7 +426,7 @@ class ImportOperationTest(ImportTest, TestCase): current_ope_nb = models.Operation.objects.count() self.assertEqual(current_ope_nb, first_ope_nb + 2) - modern = models.Period.objects.get(txt_idx='modern') + modern = models.Period.objects.get(txt_idx="modern") for ope in models.Operation.objects.order_by("-pk")[0:2]: self.assertIn(modern, list(ope.periods.all())) target.delete() @@ -361,8 +435,7 @@ class ImportOperationTest(ImportTest, TestCase): def test_import_value_format(self): importer, form = self.init_ope_import() column = importer.columns.get(col_number=1) - f = ValueFormater.objects.create(name="-", slug="-", - format_string="oa-{}") + f = ValueFormater.objects.create(name="-", slug="-", format_string="oa-{}") column.value_format = f column.save() @@ -372,11 +445,11 @@ class ImportOperationTest(ImportTest, TestCase): self.init_ope_targetkey(imp=impt) impt.importation() self.assertEqual( - models.Operation.objects.filter(code_patriarche='oa-4201').count(), - 1) + models.Operation.objects.filter(code_patriarche="oa-4201").count(), 1 + ) self.assertEqual( - models.Operation.objects.filter(code_patriarche='oa-4200').count(), - 1) + models.Operation.objects.filter(code_patriarche="oa-4200").count(), 1 + ) f.delete() def test_keys_limitation(self): @@ -428,13 +501,10 @@ class ImportOperationTest(ImportTest, TestCase): self.init_ope_targetkey(imp=impt) impt.importation() self.assertEqual(len(impt.errors), 2) + self.assertTrue("cody" in impt.errors[0]["error"]) self.assertTrue( - "cody" in impt.errors[0]['error'] - ) - self.assertTrue( - "Importer configuration error" in impt.errors[0]['error'] or - "Erreur de configuration de l\'importeur" in - impt.errors[0]['error'] + "Importer configuration error" in impt.errors[0]["error"] + or "Erreur de configuration de l'importeur" in impt.errors[0]["error"] ) def test_model_limitation(self): @@ -450,15 +520,15 @@ class ImportOperationTest(ImportTest, TestCase): current_ope_nb = models.Operation.objects.count() self.assertEqual(current_ope_nb, init_ope_number + 2) - for ope in models.Operation.objects.order_by('-pk').all()[:2]: + for ope in models.Operation.objects.order_by("-pk").all()[:2]: ope.delete() importer, form = self.init_ope_import() # add an inadequate model to make created_models non empty importer.created_models.clear() - importer.created_models.add(ImporterModel.objects.get( - klass='ishtar_common.models.Organization' - )) + importer.created_models.add( + ImporterModel.objects.get(klass="ishtar_common.models.Organization") + ) impt = form.save(self.ishtar_user) impt.initialize() self.init_ope_targetkey(imp=impt) @@ -471,9 +541,11 @@ class ImportOperationTest(ImportTest, TestCase): importer, form = self.init_ope_import() # add operation model to allow creation importer.created_models.clear() - importer.created_models.add(ImporterModel.objects.get( - klass='archaeological_operations.models.Operation' - )) + importer.created_models.add( + ImporterModel.objects.get( + klass="archaeological_operations.models.Operation" + ) + ) impt = form.save(self.ishtar_user) impt.initialize() self.init_ope_targetkey(imp=impt) @@ -489,23 +561,25 @@ class ImportOperationTest(ImportTest, TestCase): mcc_operation = ImporterType.objects.get(name="MCC - Opérations") generated_file = mcc_operation.get_libreoffice_template() zip_file = zipfile.ZipFile(generated_file) - self.assertIsNone(zip_file.testzip(), "Libreoffice template generated " - "is not a correct zip file.") + self.assertIsNone( + zip_file.testzip(), + "Libreoffice template generated " "is not a correct zip file.", + ) filename = None for name in zip_file.namelist(): - if name == 'content.xml': + if name == "content.xml": filename = name break self.assertIsNotNone(filename) # only check that all operation types are listed in the source file - with tempfile.TemporaryDirectory(prefix='tmp-ishtar-') as tmpdir: + with tempfile.TemporaryDirectory(prefix="tmp-ishtar-") as tmpdir: imported_file = zip_file.extract(filename, tmpdir) with open(imported_file) as content_file: content = content_file.read() for ope_type in models.OperationType.objects.all(): - ope_type = str(ope_type).replace("'", ''') + ope_type = str(ope_type).replace("'", "'") self.assertIn(ope_type, content) def test_mcc_import_parcels(self): @@ -519,18 +593,16 @@ class ImportOperationTest(ImportTest, TestCase): self.assertEqual(current_nb, old_nb + 3) # and well imported - last_parcels = models.Parcel.objects.order_by('-pk').all()[0:3] - external_ids = sorted(['4200-59350-YY55', '4200-75101-XXXX', - '4201-59350-YY55']) - parcel_numbers = sorted(['42', '55', '55']) - sections = sorted(['ZX', 'YY', 'YY']) - self.assertEqual(external_ids, - sorted([p.external_id for p in last_parcels])) - self.assertEqual(parcel_numbers, - sorted([p.parcel_number for p in last_parcels])) - self.assertEqual(sections, - sorted([p.section for p in last_parcels])) - ope1 = models.Operation.objects.get(code_patriarche='4200') + last_parcels = models.Parcel.objects.order_by("-pk").all()[0:3] + external_ids = sorted(["4200-59350-YY55", "4200-75101-XXXX", "4201-59350-YY55"]) + parcel_numbers = sorted(["42", "55", "55"]) + sections = sorted(["ZX", "YY", "YY"]) + self.assertEqual(external_ids, sorted([p.external_id for p in last_parcels])) + self.assertEqual( + parcel_numbers, sorted([p.parcel_number for p in last_parcels]) + ) + self.assertEqual(sections, sorted([p.section for p in last_parcels])) + ope1 = models.Operation.objects.get(code_patriarche="4200") towns_ope = ope1.towns.all() imported = [imp for acc, imp in impt.get_all_imported()] for p in last_parcels: @@ -539,13 +611,14 @@ class ImportOperationTest(ImportTest, TestCase): self.assertEqual(len(imported), len(last_parcels)) self.assertEqual( models.Parcel.objects.get( - parcel_number='55', section='YY', - operation_id=ope1.pk).external_id, - '4200-59350-YY55') + parcel_number="55", section="YY", operation_id=ope1.pk + ).external_id, + "4200-59350-YY55", + ) # cached_label update - ope2 = models.Operation.objects.get(code_patriarche='4201') + ope2 = models.Operation.objects.get(code_patriarche="4201") self.assertIsNotNone(ope2.cached_label) - self.assertIn('LILLE', ope2.cached_label.upper()) + self.assertIn("LILLE", ope2.cached_label.upper()) # delete associated parcel with the import deletion parcel_count = models.Parcel.objects.count() impt.delete() @@ -553,105 +626,113 @@ class ImportOperationTest(ImportTest, TestCase): def test_json_fields(self): importer, form = self.init_ope_import("operations-with-json-fields.csv") - col = ImporterColumn.objects.create(importer_type=importer, - col_number=11) - formater_type = FormaterType.objects.get( - formater_type='IntegerFormater') + col = ImporterColumn.objects.create(importer_type=importer, col_number=11) + formater_type = FormaterType.objects.get(formater_type="IntegerFormater") it = ImportTarget.objects.create( - column=col, target='data__autre_refs__arbitraire', - formater_type=formater_type) + column=col, + target="data__autre_refs__arbitraire", + formater_type=formater_type, + ) impt = form.save(self.ishtar_user) impt.initialize() self.init_ope_targetkey(imp=impt) impt.importation() - ope1 = models.Operation.objects.get(code_patriarche='4200') - self.assertEqual(ope1.data, {'autre_refs': {'arbitraire': 789}}) - ope2 = models.Operation.objects.get(code_patriarche='4201') - self.assertEqual(ope2.data, {'autre_refs': {'arbitraire': 456}}) + ope1 = models.Operation.objects.get(code_patriarche="4200") + self.assertEqual(ope1.data, {"autre_refs": {"arbitraire": 789}}) + ope2 = models.Operation.objects.get(code_patriarche="4201") + self.assertEqual(ope2.data, {"autre_refs": {"arbitraire": 456}}) # #4292: Import of new JSON fields erase all precedent JSON fields it.delete() - col2 = ImporterColumn.objects.create(importer_type=importer, - col_number=12) + col2 = ImporterColumn.objects.create(importer_type=importer, col_number=12) ImportTarget.objects.create( - column=col2, target='data__autre', - formater_type=formater_type) + column=col2, target="data__autre", formater_type=formater_type + ) impt = form.save(self.ishtar_user) impt.initialize() self.init_ope_targetkey(imp=impt) impt.importation() - ope1 = models.Operation.objects.get(code_patriarche='4200') - self.assertEqual(ope1.data, {'autre_refs': {'arbitraire': 789}, - "autre": 666}) - ope2 = models.Operation.objects.get(code_patriarche='4201') - self.assertEqual(ope2.data, {'autre_refs': {'arbitraire': 456}, - "autre": 333}) + ope1 = models.Operation.objects.get(code_patriarche="4200") + self.assertEqual(ope1.data, {"autre_refs": {"arbitraire": 789}, "autre": 666}) + ope2 = models.Operation.objects.get(code_patriarche="4201") + self.assertEqual(ope2.data, {"autre_refs": {"arbitraire": 456}, "autre": 333}) def test_regexp(self): importer, form = self.init_ope_import("operations-with-json-fields.csv") r, __ = Regexp.objects.get_or_create( - name="Code INSEE", - regexp='([0-9]{0,1}[0-9A-B]) *([0-9]{3})' + name="Code INSEE", regexp="([0-9]{0,1}[0-9A-B]) *([0-9]{3})" ) col = ImporterColumn.objects.create( - importer_type=importer, col_number=13, regexp_pre_filter=r) + importer_type=importer, col_number=13, regexp_pre_filter=r + ) formater_type = FormaterType.objects.get( - formater_type='UnicodeFormater', options="") + formater_type="UnicodeFormater", options="" + ) ImportTarget.objects.create( - column=col, target='data__code_insee', - formater_type=formater_type) + column=col, target="data__code_insee", formater_type=formater_type + ) impt = form.save(self.ishtar_user) impt.initialize() self.init_ope_targetkey(imp=impt) impt.importation() - ope1 = models.Operation.objects.get(code_patriarche='4200') + ope1 = models.Operation.objects.get(code_patriarche="4200") self.assertEqual(ope1.data, {"code_insee": "45123"}) - ope2 = models.Operation.objects.get(code_patriarche='4201') + ope2 = models.Operation.objects.get(code_patriarche="4201") self.assertEqual(ope2.data, {"code_insee": "6456"}) class ImportDocumentTest(ImportTest, TestCase): fixtures = OPERATION_TOWNS_FIXTURES - def init_doc_import(self, filename='document-example.csv'): + def init_doc_import(self, filename="document-example.csv"): model, __ = ImporterModel.objects.get_or_create( - klass="ishtar_common.models.Document", - defaults={ - "name": "Documentation" - } + klass="ishtar_common.models.Document", defaults={"name": "Documentation"} ) doc_import, __ = ImporterType.objects.get_or_create( - name="Doc import", slug="doc-import", associated_models=model) - - col = ImporterColumn.objects.create(col_number=1, - importer_type_id=doc_import.pk) - formater = FormaterType.objects.filter( - formater_type='IntegerFormater').all()[0] - ImportTarget.objects.create(target='import_get_next_index', - formater_type_id=formater.pk, - column_id=col.pk) - col = ImporterColumn.objects.create(col_number=2, - importer_type_id=doc_import.pk) + name="Doc import", slug="doc-import", associated_models=model + ) + + col = ImporterColumn.objects.create( + col_number=1, importer_type_id=doc_import.pk + ) + formater = FormaterType.objects.filter(formater_type="IntegerFormater").all()[0] + ImportTarget.objects.create( + target="import_get_next_index", + formater_type_id=formater.pk, + column_id=col.pk, + ) + col = ImporterColumn.objects.create( + col_number=2, importer_type_id=doc_import.pk + ) formater, __ = FormaterType.objects.get_or_create( - formater_type='UnicodeFormater', options=None) - ImportTarget.objects.create(target='title', - formater_type_id=formater.pk, - column_id=col.pk) + formater_type="UnicodeFormater", options=None + ) + ImportTarget.objects.create( + target="title", formater_type_id=formater.pk, column_id=col.pk + ) doc_import_file = open( - settings.ROOT_PATH + - '../archaeological_operations/tests/' + filename, - 'rb') + settings.ROOT_PATH + "../archaeological_operations/tests/" + filename, "rb" + ) - file_dict = {'imported_file': SimpleUploadedFile( - doc_import_file.name, doc_import_file.read())} + file_dict = { + "imported_file": SimpleUploadedFile( + doc_import_file.name, doc_import_file.read() + ) + } group, c = TargetKeyGroup.objects.get_or_create(name="My group") - post_dict = {'importer_type': doc_import.pk, 'skip_lines': 1, - "encoding": 'utf-8', "name": 'init_ope_import', - "associated_group": group.pk, "csv_sep": ","} - form = forms_common.NewImportForm(data=post_dict, files=file_dict, - user=self.user) + post_dict = { + "importer_type": doc_import.pk, + "skip_lines": 1, + "encoding": "utf-8", + "name": "init_ope_import", + "associated_group": group.pk, + "csv_sep": ",", + } + form = forms_common.NewImportForm( + data=post_dict, files=file_dict, user=self.user + ) form.is_valid() return doc_import, form @@ -681,8 +762,9 @@ class ImportStepByStepTest(ImportTest, TestCase): first_person_nb = Person.objects.count() first_ope_nb = models.Operation.objects.count() - import_url = reverse('import_step_by_step', - kwargs={'pk': impt.pk, 'line_number': 2}) + import_url = reverse( + "import_step_by_step", kwargs={"pk": impt.pk, "line_number": 2} + ) response = c.get(import_url) # no login redirect self.assertEqual(response.status_code, 302) @@ -692,12 +774,13 @@ class ImportStepByStepTest(ImportTest, TestCase): response = c.get(import_url) self.assertEqual(response.status_code, 200) # verify pagination for next link is OK - self.assertIn('href="/import-step-by-step/{}/3/"'.format(impt.pk), - response.content.decode()) + self.assertIn( + 'href="/import-step-by-step/{}/3/"'.format(impt.pk), + response.content.decode(), + ) # creation have been evaluated self.assertIn( - str(_("New objects will be created.")), - response.content.decode('utf-8') + str(_("New objects will be created.")), response.content.decode("utf-8") ) # import this line @@ -705,8 +788,9 @@ class ImportStepByStepTest(ImportTest, TestCase): response = c.post(import_url, posted) self.assertEqual(response.status_code, 302) # successful import - go to the next line - new_import_url = reverse('import_step_by_step', - kwargs={'pk': impt.pk, 'line_number': 3}) + new_import_url = reverse( + "import_step_by_step", kwargs={"pk": impt.pk, "line_number": 3} + ) self.assertRedirects(response, new_import_url) current_ope_nb = models.Operation.objects.count() self.assertEqual(current_ope_nb, first_ope_nb + 1) @@ -727,12 +811,13 @@ class ImportStepByStepTest(ImportTest, TestCase): self.assertEqual(response.status_code, 200) self.assertIn( str(_("This line have been already imported.")), - response.content.decode('utf-8') + response.content.decode("utf-8"), ) # import next page next_import_url = reverse( - 'import_step_by_step', kwargs={'pk': impt.pk, 'line_number': 3}) + "import_step_by_step", kwargs={"pk": impt.pk, "line_number": 3} + ) posted = {"valid": "import"} c.post(next_import_url, posted) current_ope_nb = models.Operation.objects.count() @@ -761,11 +846,13 @@ class ImportStepByStepTest(ImportTest, TestCase): imported_line = fle.readline() self.assertIn("2000/01/32", imported_line) # error detected on the source file - error = str(_( - "The following error(s) has been encountered while parsing " - "the source file:") + error = str( + _( + "The following error(s) has been encountered while parsing " + "the source file:" + ) ) - self.assertIn(error, response.content.decode('utf-8')) + self.assertIn(error, response.content.decode("utf-8")) class SerializationTest(GenericSerializationTest, TestCase): @@ -773,69 +860,73 @@ class SerializationTest(GenericSerializationTest, TestCase): def setUp(self): self.username, self.password, self.user = create_superuser() - operation = create_operation(self.user, - values={"code_patriarche": "66666"}) + operation = create_operation(self.user, values={"code_patriarche": "66666"}) ope2 = create_operation(self.user, values={"code_patriarche": "66667"}) self.operations = [operation, ope2] models.RecordRelations.objects.create( - left_record=operation, right_record=ope2, - relation_type=models.RelationType.objects.all()[0] - ) - site = models.ArchaeologicalSite.objects.create( - reference="ref-site" + left_record=operation, + right_record=ope2, + relation_type=models.RelationType.objects.all()[0], ) + site = models.ArchaeologicalSite.objects.create(reference="ref-site") operation.archaeological_sites.add(site) operation.top_sites.add(site) - default = {"town": Town.objects.create(numero_insee="66666"), - "section": 'A', 'parcel_number': '1', "operation": operation} + default = { + "town": Town.objects.create(numero_insee="66666"), + "section": "A", + "parcel_number": "1", + "operation": operation, + } parcel = models.Parcel.objects.create(**default) models.ParcelOwner.objects.create( - parcel=parcel, owner=Person.objects.create(), - start_date=datetime.date.today(), end_date=datetime.date.today()) + parcel=parcel, + owner=Person.objects.create(), + start_date=datetime.date.today(), + end_date=datetime.date.today(), + ) def test_serialization(self): - res = self.generic_serialization_test( - serializers.operation_serialization) + res = self.generic_serialization_test(serializers.operation_serialization) ope_json = json.loads( - res[('operations', 'archaeological_operations__Operation')] + res[("operations", "archaeological_operations__Operation")] ) self.assertEqual(len(ope_json), 2) - result_queryset = models.Operation.objects.filter( - code_patriarche="66666") + result_queryset = models.Operation.objects.filter(code_patriarche="66666") res = self.generic_serialization_test( - serializers.operation_serialization, no_test=True, - kwargs={"operation_queryset": result_queryset} + serializers.operation_serialization, + no_test=True, + kwargs={"operation_queryset": result_queryset}, ) ope_json = json.loads( - res[('operations', 'archaeological_operations__Operation')] + res[("operations", "archaeological_operations__Operation")] ) self.assertEqual(len(ope_json), 1) site_json = json.loads( - res[('operations', 'archaeological_operations__ArchaeologicalSite')] + res[("operations", "archaeological_operations__ArchaeologicalSite")] ) self.assertEqual(len(site_json), 1) rel_json = json.loads( - res[('operations', 'archaeological_operations__RecordRelations')] + res[("operations", "archaeological_operations__RecordRelations")] ) self.assertEqual(len(rel_json), 0) - result_queryset = models.Operation.objects.filter( - code_patriarche="66667") + result_queryset = models.Operation.objects.filter(code_patriarche="66667") res = self.generic_serialization_test( - serializers.operation_serialization, no_test=True, - kwargs={"operation_queryset": result_queryset} + serializers.operation_serialization, + no_test=True, + kwargs={"operation_queryset": result_queryset}, ) ope_json = json.loads( - res[('operations', 'archaeological_operations__Operation')] + res[("operations", "archaeological_operations__Operation")] ) self.assertEqual(len(ope_json), 1) site_json = json.loads( - res[('operations', 'archaeological_operations__ArchaeologicalSite')] + res[("operations", "archaeological_operations__ArchaeologicalSite")] ) self.assertEqual(len(site_json), 0) rel_json = json.loads( - res[('operations', 'archaeological_operations__RecordRelations')] + res[("operations", "archaeological_operations__RecordRelations")] ) self.assertEqual(len(rel_json), 0) @@ -849,8 +940,10 @@ class SerializationTest(GenericSerializationTest, TestCase): def test_lock(self): self.reinit_lock() self.generic_serialization_test( - serializers.operation_serialization, no_test=True, - kwargs={"put_locks": False}) + serializers.operation_serialization, + no_test=True, + kwargs={"put_locks": False}, + ) for operation in self.operations: operation = models.Operation.objects.get(pk=operation.pk) self.assertFalse(operation.locked) @@ -858,8 +951,10 @@ class SerializationTest(GenericSerializationTest, TestCase): self.reinit_lock() self.generic_serialization_test( - serializers.operation_serialization, no_test=True, - kwargs={"put_locks": True}) + serializers.operation_serialization, + no_test=True, + kwargs={"put_locks": True}, + ) for operation in self.operations: operation = models.Operation.objects.get(pk=operation.pk) self.assertTrue(operation.locked) @@ -867,8 +962,10 @@ class SerializationTest(GenericSerializationTest, TestCase): self.reinit_lock() self.generic_serialization_test( - serializers.operation_serialization, no_test=True, - kwargs={"put_locks": True, "lock_user": self.user}) + serializers.operation_serialization, + no_test=True, + kwargs={"put_locks": True, "lock_user": self.user}, + ) for operation in self.operations: operation = models.Operation.objects.get(pk=operation.pk) self.assertTrue(operation.locked) @@ -876,40 +973,50 @@ class SerializationTest(GenericSerializationTest, TestCase): def test_restore(self): current_number, zip_filename = self.generic_restore_test_genzip( - serializers.OPERATION_MODEL_LIST, - serializers.operation_serialization) - self.generic_restore_test(zip_filename, current_number, - serializers.OPERATION_MODEL_LIST) + serializers.OPERATION_MODEL_LIST, serializers.operation_serialization + ) + self.generic_restore_test( + zip_filename, current_number, serializers.OPERATION_MODEL_LIST + ) def test_unlock_on_restore(self): current_number, zip_filename = self.generic_restore_test_genzip( serializers.OPERATION_MODEL_LIST, serializers.operation_serialization, - kwargs={"put_locks": True, "lock_user": self.user}) + kwargs={"put_locks": True, "lock_user": self.user}, + ) - self.generic_restore_test(zip_filename, current_number, - serializers.OPERATION_MODEL_LIST, - delete_existing=False) + self.generic_restore_test( + zip_filename, + current_number, + serializers.OPERATION_MODEL_LIST, + delete_existing=False, + ) for operation in self.operations: operation = models.Operation.objects.get( - code_patriarche=operation.code_patriarche) + code_patriarche=operation.code_patriarche + ) self.assertTrue(operation.locked) self.assertEqual(operation.lock_user, self.user) - self.generic_restore_test(zip_filename, current_number, - serializers.OPERATION_MODEL_LIST, - delete_existing=False, - release_locks=True) + self.generic_restore_test( + zip_filename, + current_number, + serializers.OPERATION_MODEL_LIST, + delete_existing=False, + release_locks=True, + ) for operation in self.operations: operation = models.Operation.objects.get( - code_patriarche=operation.code_patriarche) + code_patriarche=operation.code_patriarche + ) self.assertFalse(operation.locked) self.assertIsNone(operation.lock_user) def test_historization_on_restore(self): current_number, zip_filename = self.generic_restore_test_genzip( - serializers.OPERATION_MODEL_LIST, - serializers.operation_serialization) + serializers.OPERATION_MODEL_LIST, serializers.operation_serialization + ) operation = models.Operation.objects.get(code_patriarche="66666") version_nb = operation.history.count() @@ -941,191 +1048,516 @@ class ParcelTest(ImportTest, TestCase): def test_parse_parcels(self): # the database needs to be initialised before importing from archaeological_operations.utils import parse_parcels + # default_town = Town.objects.create(numero_insee="12345", # name="default_town") test_values = ( - ("1996 : XT:53,54,56,57,59,60,61,62", - {1996: [ - ("XT", "53"), ("XT", "54"), ("XT", "56"), ("XT", "57"), - ("XT", "59"), ("XT", "60"), ("XT", "61"), ("XT", "62"), - ]} - ), - ("AD:23", - {None: [ - ("AD", "23") - ]}), - ("1961 :B1:227;", - {1961: [ - ("B1", '227') - ]}), - ("1982 CV:35;CV:36", - {1982: [ - ("CV", "35"), ("CV", "36"), - ]}), - ("E:24;E:25", - {None: [ - ("E", "24"), ("E", "25"), - ]}), - ("B : 375, 376, 386, 387, 645, 646 / C : 412 à 415, 432 à 435, " - "622 / F : 120, 149, 150, 284, 287, 321 à 323", - {None: [ - ("B", "375"), ("B", "376"), ("B", "386"), ("B", "387"), - ("B", "645"), ("B", "646"), - ("C", "412"), ("C", "413"), ("C", "414"), ("C", "415"), - ("C", "432"), ("C", "433"), ("C", "434"), ("C", "435"), - ("C", "622"), - ("F", "120"), ("F", "149"), ("F", "150"), ("F", "284"), - ("F", "287"), ("F", "321"), ("F", "322"), ("F", "323"), - ]}), - ("AD : 95, 96, 86, 87, 81, 252, AE : 58, AD : 115 à 132", - {None: [ - ("AD", "95"), ("AD", "96"), ("AD", "86"), ("AD", "87"), - ("AD", "81"), ("AD", "252"), ("AD", "115"), ("AD", "116"), - ("AD", "117"), ("AD", "118"), ("AD", "119"), ("AD", "120"), - ("AD", "121"), ("AD", "122"), ("AD", "123"), ("AD", "124"), - ("AD", "125"), ("AD", "126"), ("AD", "127"), ("AD", "128"), - ("AD", "129"), ("AD", "130"), ("AD", "131"), ("AD", "132"), - ("AE", "58"), - ]}), - ("XD:1 à 13, 24 à 28, 33 à 39, 50 à 52, 80, 83, 84 à 86, 259 à " - "261, 182, 225 ; XH:5 ; P:1640, 1888, 1889, 1890 ; R:1311, " - "1312, 1314,1342, 1343, 1559 à 1569", - {None: [ - ('XD', "1"), ('XD', "2"), ('XD', "3"), ('XD', "4"), - ('XD', "5"), ('XD', "6"), ('XD', "7"), ('XD', "8"), - ('XD', "9"), ('XD', "10"), ('XD', "11"), ('XD', "12"), - ('XD', "13"), ("XD", "24"), ("XD", "25"), ("XD", "26"), - ("XD", "27"), ("XD", "28"), ("XD", "33"), ("XD", "34"), - ("XD", "35"), ("XD", "36"), ("XD", "37"), ("XD", "38"), - ("XD", "39"), ("XD", "50"), ("XD", "51"), ("XD", "52"), - ("XD", "80"), ("XD", "83"), ("XD", "84"), ("XD", "85"), - ("XD", "86"), ("XD", "259"), ("XD", "260"), ("XD", "261"), - ("XD", "182"), ("XD", "225"), ("XH", "5"), - ("P", "1640"), ("P", "1888"), ("P", "1889"), ("P", "1890"), - ("R", "1311"), ("R", "1312"), ("R", "1314"), ("R", "1342"), - ("R", "1343"), ("R", "1559"), ("R", "1560"), ("R", "1561"), - ("R", "1562"), ("R", "1563"), ("R", "1564"), ("R", "1565"), - ("R", "1566"), ("R", "1567"), ("R", "1568"), ("R", "1569"), - ]}), - ("BZ:2 à 5, 365 ; CD:88 à 104, 106, 108, 326", - {None: [ - ('BZ', '2'), ('BZ', '3'), ('BZ', '4'), ('BZ', '5'), - ('BZ', '365'), ('CD', '88'), ('CD', '89'), ('CD', '90'), - ('CD', '91'), ('CD', '92'), ('CD', '93'), ('CD', '94'), - ('CD', '95'), ('CD', '96'), ('CD', '97'), ('CD', '98'), - ('CD', '99'), ('CD', '100'), ('CD', '101'), ('CD', '102'), - ('CD', '103'), ('CD', '104'), ('CD', '106'), ('CD', '326'), - ('CD', '108') - ]}), - ("AV 118 à 125, 127, 132 à 137, 153, 398p, 399, 402; BI 27, 30, " - "32, 33, 188, 255, 256 à 258, 260, 284p, 294; BL 297", - {None: [ - ('AV', '118'), ('AV', '119'), ('AV', '120'), ('AV', '121'), - ('AV', '122'), ('AV', '123'), ('AV', '124'), ('AV', '125'), - ('AV', '127'), ('AV', '132'), ('AV', '133'), ('AV', '134'), - ('AV', '135'), ('AV', '136'), ('AV', '137'), ('AV', '153'), - ('AV', '398p'), ('AV', '399'), ('AV', '402'), - ('BI', '27'), ('BI', '30'), ('BI', '32'), ('BI', '33'), - ('BI', '188'), ('BI', '255'), ('BI', '256'), ('BI', '257'), - ('BI', '258'), ('BI', '260'), ('BI', '284p'), ('BI', '294'), - ('BL', '297'), - ]}), - ("A : 904 à 906, 911 ; E:40, 41", - {None: [ - ("A", '904'), ("A", '905'), ("A", '906'), ("A", '911'), - ("E", '40'), ("E", "41") - ]}), - ("1991 : BE:8, 12", - {"1991": [ - ('BE', '8'), ('BE', '12'), - ]}), - ("1979 : EM:1", - {"1979": [ - ('EM', '1') - ]},), - ("B:448;B:449;B:450;B:451;B:452;B:455;B:456;B:457;B:458;B:459;" - "B:1486;", - {None: [ - ("B", "448"), ("B", "449"), ("B", "450"), ("B", "451"), - ("B", "452"), ("B", "455"), ("B", "456"), ("B", "457"), - ("B", "458"), ("B", "459"), ("B", "1486"), - ]}), - ("AC : 72 à 81, 91 à 100, 197 / ZC:180 à 189", - {None: [ - ('AC', '72'), ('AC', '73'), ('AC', '74'), ('AC', '75'), - ('AC', '76'), ('AC', '77'), ('AC', '78'), ('AC', '79'), - ('AC', '80'), ('AC', '81'), ('AC', '91'), ('AC', '92'), - ('AC', '93'), ('AC', '94'), ('AC', '95'), ('AC', '96'), - ('AC', '97'), ('AC', '98'), ('AC', '99'), ('AC', '100'), - ('AC', '197'), ('ZC', '180'), ('ZC', '181'), ('ZC', '182'), - ('ZC', '183'), ('ZC', '184'), ('ZC', '185'), ('ZC', '186'), - ('ZC', '187'), ('ZC', '188'), ('ZC', '189'), - ]}), - ("AB 37 et 308", - {None: [ - ('AB', '37'), ('AB', '308'), - ]}), - ("1983 D2 n° 458 et 459", - {"1983": [ - ('D2', '458'), ('D2', '459'), - ]}), - ("ZS : 21p, 66", - {None: [ - ('ZS', '21p'), ('ZS', '66'), - ]}), - ("VV:166, 167, domaine public", - {None: [ - ('VV', '166'), ('VV', '167'), - ]}), - (" AS:13 à 15, 17 à 19, 21 à 32, 34 à 45, 47 à 53, 69, 70, 82, " - "84 / CK:1, 24, 25, 29, 30, 37 à 43", - {None: [ - ("AS", "13"), ("AS", "14"), ("AS", "15"), ("AS", "17"), - ("AS", "18"), ("AS", "19"), ("AS", "21"), ("AS", "22"), - ("AS", "23"), ("AS", "24"), ("AS", "25"), ("AS", "26"), - ("AS", "27"), ("AS", "28"), ("AS", "29"), ("AS", "30"), - ("AS", "31"), ("AS", "32"), ("AS", "34"), ("AS", "35"), - ("AS", "36"), ("AS", "37"), ("AS", "38"), ("AS", "39"), - ("AS", "40"), ("AS", "41"), ("AS", "42"), ("AS", "43"), - ("AS", "44"), ("AS", "45"), ("AS", "47"), ("AS", "48"), - ("AS", "49"), ("AS", "50"), ("AS", "51"), ("AS", "52"), - ("AS", "53"), ('AS', "69"), ('AS', "70"), ('AS', "82"), - ('AS', "84"), ('CK', "1"), ('CK', "24"), ('CK', "25"), - ('CK', "29"), ('CK', "30"), ('CK', "37"), ('CK', "38"), - ('CK', "39"), ('CK', "40"), ('CK', "41"), ('CK', "42"), - ('CK', "43"), ]}), - (" ZN:37, 15, 35, 28, 29 / ZM:9, 73", - {None: [ - ("ZN", "37"), ("ZN", "15"), ("ZN", "35"), ("ZN", "28"), - ("ZN", "29"), ("ZM", "9"), ("ZM", "73"), - ]}), - (" Tranche n°1 : YP:243, 12, 14 à 16, 18 à 26, DP / Tranche n°2 :" - "YP:17, 307, 27, 308, 44 à 46, 683, BM:1, 250, 488 à 492", - {None: [ - ('YP', '243'), ('YP', '12'), ('YP', '14'), ('YP', '15'), - ('YP', '16'), ('YP', '18'), ('YP', '19'), ('YP', '20'), - ('YP', '21'), ('YP', '22'), ('YP', '23'), ('YP', '24'), - ('YP', '25'), ('YP', '26'), ('YP', '17'), ('YP', '27'), - ('YP', '308'), ('YP', '44'), ('YP', '45'), ('YP', '46'), - ('YP', '683'), ('YP', '307'), ('BM', '1'), ('BM', '250'), - ('BM', '488'), ('BM', '489'), ('BM', '490'), ('BM', '491'), - ('BM', '492'), - ]}), - (" H : 106, 156, 158", - {None: [ - ('H', '106'), ('H', '156'), ('H', '158'), - ]}), - ("Section YO : parcelles n° 19; 20", - {None: [ - ('YO', '19'), ('YO', '20'), - ]}), - ("1991 :AI:23;19;20;21;22;181;AM:116;214;215;233;235", - {"1991": [ - ("AI", "19"), ("AI", "20"), ("AI", "21"), ("AI", "22"), - ("AI", "23"), ("AI", "181"), - ("AM", "116"), ("AM", "214"), ("AM", "215"), - ("AM", "233"), ("AM", "235"), - ]}) + ( + "1996 : XT:53,54,56,57,59,60,61,62", + { + 1996: [ + ("XT", "53"), + ("XT", "54"), + ("XT", "56"), + ("XT", "57"), + ("XT", "59"), + ("XT", "60"), + ("XT", "61"), + ("XT", "62"), + ] + }, + ), + ("AD:23", {None: [("AD", "23")]}), + ("1961 :B1:227;", {1961: [("B1", "227")]}), + ( + "1982 CV:35;CV:36", + { + 1982: [ + ("CV", "35"), + ("CV", "36"), + ] + }, + ), + ( + "E:24;E:25", + { + None: [ + ("E", "24"), + ("E", "25"), + ] + }, + ), + ( + "B : 375, 376, 386, 387, 645, 646 / C : 412 à 415, 432 à 435, " + "622 / F : 120, 149, 150, 284, 287, 321 à 323", + { + None: [ + ("B", "375"), + ("B", "376"), + ("B", "386"), + ("B", "387"), + ("B", "645"), + ("B", "646"), + ("C", "412"), + ("C", "413"), + ("C", "414"), + ("C", "415"), + ("C", "432"), + ("C", "433"), + ("C", "434"), + ("C", "435"), + ("C", "622"), + ("F", "120"), + ("F", "149"), + ("F", "150"), + ("F", "284"), + ("F", "287"), + ("F", "321"), + ("F", "322"), + ("F", "323"), + ] + }, + ), + ( + "AD : 95, 96, 86, 87, 81, 252, AE : 58, AD : 115 à 132", + { + None: [ + ("AD", "95"), + ("AD", "96"), + ("AD", "86"), + ("AD", "87"), + ("AD", "81"), + ("AD", "252"), + ("AD", "115"), + ("AD", "116"), + ("AD", "117"), + ("AD", "118"), + ("AD", "119"), + ("AD", "120"), + ("AD", "121"), + ("AD", "122"), + ("AD", "123"), + ("AD", "124"), + ("AD", "125"), + ("AD", "126"), + ("AD", "127"), + ("AD", "128"), + ("AD", "129"), + ("AD", "130"), + ("AD", "131"), + ("AD", "132"), + ("AE", "58"), + ] + }, + ), + ( + "XD:1 à 13, 24 à 28, 33 à 39, 50 à 52, 80, 83, 84 à 86, 259 à " + "261, 182, 225 ; XH:5 ; P:1640, 1888, 1889, 1890 ; R:1311, " + "1312, 1314,1342, 1343, 1559 à 1569", + { + None: [ + ("XD", "1"), + ("XD", "2"), + ("XD", "3"), + ("XD", "4"), + ("XD", "5"), + ("XD", "6"), + ("XD", "7"), + ("XD", "8"), + ("XD", "9"), + ("XD", "10"), + ("XD", "11"), + ("XD", "12"), + ("XD", "13"), + ("XD", "24"), + ("XD", "25"), + ("XD", "26"), + ("XD", "27"), + ("XD", "28"), + ("XD", "33"), + ("XD", "34"), + ("XD", "35"), + ("XD", "36"), + ("XD", "37"), + ("XD", "38"), + ("XD", "39"), + ("XD", "50"), + ("XD", "51"), + ("XD", "52"), + ("XD", "80"), + ("XD", "83"), + ("XD", "84"), + ("XD", "85"), + ("XD", "86"), + ("XD", "259"), + ("XD", "260"), + ("XD", "261"), + ("XD", "182"), + ("XD", "225"), + ("XH", "5"), + ("P", "1640"), + ("P", "1888"), + ("P", "1889"), + ("P", "1890"), + ("R", "1311"), + ("R", "1312"), + ("R", "1314"), + ("R", "1342"), + ("R", "1343"), + ("R", "1559"), + ("R", "1560"), + ("R", "1561"), + ("R", "1562"), + ("R", "1563"), + ("R", "1564"), + ("R", "1565"), + ("R", "1566"), + ("R", "1567"), + ("R", "1568"), + ("R", "1569"), + ] + }, + ), + ( + "BZ:2 à 5, 365 ; CD:88 à 104, 106, 108, 326", + { + None: [ + ("BZ", "2"), + ("BZ", "3"), + ("BZ", "4"), + ("BZ", "5"), + ("BZ", "365"), + ("CD", "88"), + ("CD", "89"), + ("CD", "90"), + ("CD", "91"), + ("CD", "92"), + ("CD", "93"), + ("CD", "94"), + ("CD", "95"), + ("CD", "96"), + ("CD", "97"), + ("CD", "98"), + ("CD", "99"), + ("CD", "100"), + ("CD", "101"), + ("CD", "102"), + ("CD", "103"), + ("CD", "104"), + ("CD", "106"), + ("CD", "326"), + ("CD", "108"), + ] + }, + ), + ( + "AV 118 à 125, 127, 132 à 137, 153, 398p, 399, 402; BI 27, 30, " + "32, 33, 188, 255, 256 à 258, 260, 284p, 294; BL 297", + { + None: [ + ("AV", "118"), + ("AV", "119"), + ("AV", "120"), + ("AV", "121"), + ("AV", "122"), + ("AV", "123"), + ("AV", "124"), + ("AV", "125"), + ("AV", "127"), + ("AV", "132"), + ("AV", "133"), + ("AV", "134"), + ("AV", "135"), + ("AV", "136"), + ("AV", "137"), + ("AV", "153"), + ("AV", "398p"), + ("AV", "399"), + ("AV", "402"), + ("BI", "27"), + ("BI", "30"), + ("BI", "32"), + ("BI", "33"), + ("BI", "188"), + ("BI", "255"), + ("BI", "256"), + ("BI", "257"), + ("BI", "258"), + ("BI", "260"), + ("BI", "284p"), + ("BI", "294"), + ("BL", "297"), + ] + }, + ), + ( + "A : 904 à 906, 911 ; E:40, 41", + { + None: [ + ("A", "904"), + ("A", "905"), + ("A", "906"), + ("A", "911"), + ("E", "40"), + ("E", "41"), + ] + }, + ), + ( + "1991 : BE:8, 12", + { + "1991": [ + ("BE", "8"), + ("BE", "12"), + ] + }, + ), + ( + "1979 : EM:1", + {"1979": [("EM", "1")]}, + ), + ( + "B:448;B:449;B:450;B:451;B:452;B:455;B:456;B:457;B:458;B:459;" + "B:1486;", + { + None: [ + ("B", "448"), + ("B", "449"), + ("B", "450"), + ("B", "451"), + ("B", "452"), + ("B", "455"), + ("B", "456"), + ("B", "457"), + ("B", "458"), + ("B", "459"), + ("B", "1486"), + ] + }, + ), + ( + "AC : 72 à 81, 91 à 100, 197 / ZC:180 à 189", + { + None: [ + ("AC", "72"), + ("AC", "73"), + ("AC", "74"), + ("AC", "75"), + ("AC", "76"), + ("AC", "77"), + ("AC", "78"), + ("AC", "79"), + ("AC", "80"), + ("AC", "81"), + ("AC", "91"), + ("AC", "92"), + ("AC", "93"), + ("AC", "94"), + ("AC", "95"), + ("AC", "96"), + ("AC", "97"), + ("AC", "98"), + ("AC", "99"), + ("AC", "100"), + ("AC", "197"), + ("ZC", "180"), + ("ZC", "181"), + ("ZC", "182"), + ("ZC", "183"), + ("ZC", "184"), + ("ZC", "185"), + ("ZC", "186"), + ("ZC", "187"), + ("ZC", "188"), + ("ZC", "189"), + ] + }, + ), + ( + "AB 37 et 308", + { + None: [ + ("AB", "37"), + ("AB", "308"), + ] + }, + ), + ( + "1983 D2 n° 458 et 459", + { + "1983": [ + ("D2", "458"), + ("D2", "459"), + ] + }, + ), + ( + "ZS : 21p, 66", + { + None: [ + ("ZS", "21p"), + ("ZS", "66"), + ] + }, + ), + ( + "VV:166, 167, domaine public", + { + None: [ + ("VV", "166"), + ("VV", "167"), + ] + }, + ), + ( + " AS:13 à 15, 17 à 19, 21 à 32, 34 à 45, 47 à 53, 69, 70, 82, " + "84 / CK:1, 24, 25, 29, 30, 37 à 43", + { + None: [ + ("AS", "13"), + ("AS", "14"), + ("AS", "15"), + ("AS", "17"), + ("AS", "18"), + ("AS", "19"), + ("AS", "21"), + ("AS", "22"), + ("AS", "23"), + ("AS", "24"), + ("AS", "25"), + ("AS", "26"), + ("AS", "27"), + ("AS", "28"), + ("AS", "29"), + ("AS", "30"), + ("AS", "31"), + ("AS", "32"), + ("AS", "34"), + ("AS", "35"), + ("AS", "36"), + ("AS", "37"), + ("AS", "38"), + ("AS", "39"), + ("AS", "40"), + ("AS", "41"), + ("AS", "42"), + ("AS", "43"), + ("AS", "44"), + ("AS", "45"), + ("AS", "47"), + ("AS", "48"), + ("AS", "49"), + ("AS", "50"), + ("AS", "51"), + ("AS", "52"), + ("AS", "53"), + ("AS", "69"), + ("AS", "70"), + ("AS", "82"), + ("AS", "84"), + ("CK", "1"), + ("CK", "24"), + ("CK", "25"), + ("CK", "29"), + ("CK", "30"), + ("CK", "37"), + ("CK", "38"), + ("CK", "39"), + ("CK", "40"), + ("CK", "41"), + ("CK", "42"), + ("CK", "43"), + ] + }, + ), + ( + " ZN:37, 15, 35, 28, 29 / ZM:9, 73", + { + None: [ + ("ZN", "37"), + ("ZN", "15"), + ("ZN", "35"), + ("ZN", "28"), + ("ZN", "29"), + ("ZM", "9"), + ("ZM", "73"), + ] + }, + ), + ( + " Tranche n°1 : YP:243, 12, 14 à 16, 18 à 26, DP / Tranche n°2 :" + "YP:17, 307, 27, 308, 44 à 46, 683, BM:1, 250, 488 à 492", + { + None: [ + ("YP", "243"), + ("YP", "12"), + ("YP", "14"), + ("YP", "15"), + ("YP", "16"), + ("YP", "18"), + ("YP", "19"), + ("YP", "20"), + ("YP", "21"), + ("YP", "22"), + ("YP", "23"), + ("YP", "24"), + ("YP", "25"), + ("YP", "26"), + ("YP", "17"), + ("YP", "27"), + ("YP", "308"), + ("YP", "44"), + ("YP", "45"), + ("YP", "46"), + ("YP", "683"), + ("YP", "307"), + ("BM", "1"), + ("BM", "250"), + ("BM", "488"), + ("BM", "489"), + ("BM", "490"), + ("BM", "491"), + ("BM", "492"), + ] + }, + ), + ( + " H : 106, 156, 158", + { + None: [ + ("H", "106"), + ("H", "156"), + ("H", "158"), + ] + }, + ), + ( + "Section YO : parcelles n° 19; 20", + { + None: [ + ("YO", "19"), + ("YO", "20"), + ] + }, + ), + ( + "1991 :AI:23;19;20;21;22;181;AM:116;214;215;233;235", + { + "1991": [ + ("AI", "19"), + ("AI", "20"), + ("AI", "21"), + ("AI", "22"), + ("AI", "23"), + ("AI", "181"), + ("AM", "116"), + ("AM", "214"), + ("AM", "215"), + ("AM", "233"), + ("AM", "235"), + ] + }, + ), ) # ),("Domaine public", {} # ),("Tranche 1 : AV:4 à 6, 18, 80, 104 / partiellement : 5 et 18", {} @@ -1135,52 +1567,63 @@ class ParcelTest(ImportTest, TestCase): parcels = parse_parcels(value) if not parcels and not result: continue - self.assertTrue(parcels != [], - msg="No parcel parsed for \"%s\"" % value) + self.assertTrue(parcels != [], msg='No parcel parsed for "%s"' % value) parcels_copy = parcels[:] for year in result.keys(): for values in parcels_copy: - if values['year'] != year and \ - values['year'] != str(year): + if values["year"] != year and values["year"] != str(year): continue self.assertTrue( - (values['section'], values['parcel_number']) - in result[year], - msg="Section - Parcel number: \"%s - %s\" is not " - "in \"%s\"" % ( - values['section'], values['parcel_number'], - str(result[year]))) + (values["section"], values["parcel_number"]) in result[year], + msg='Section - Parcel number: "%s - %s" is not ' + 'in "%s"' + % ( + values["section"], + values["parcel_number"], + str(result[year]), + ), + ) parcels.pop(parcels.index(values)) - result[year].pop(result[year].index( - (values['section'], values['parcel_number']))) + result[year].pop( + result[year].index((values["section"], values["parcel_number"])) + ) # all parcels have been imported - self.assertEqual(parcels, [], msg="Parcel(s): \"%s\" haven't be " - "recognized in \"%s\"" % (str(parcels), value)) + self.assertEqual( + parcels, + [], + msg='Parcel(s): "%s" haven\'t be ' + 'recognized in "%s"' % (str(parcels), value), + ) not_imported = [data for data in result.values() if data] self.assertEqual( - not_imported, [], msg="Parcel(s): \"%s\" haven't be " - "recognized in \"%s\"" % (str(not_imported), value)) + not_imported, + [], + msg='Parcel(s): "%s" haven\'t be ' + 'recognized in "%s"' % (str(not_imported), value), + ) def create_orga(user): - orga_type, created = OrganizationType.objects.get_or_create( - txt_idx='operator') + orga_type, created = OrganizationType.objects.get_or_create(txt_idx="operator") orga, created = Organization.objects.get_or_create( - name='Operator', organization_type=orga_type, history_modifier=user) + name="Operator", organization_type=orga_type, history_modifier=user + ) return orga def create_operation(user, orga=None, values=None): - operation_type = models.OperationType.objects.get( - txt_idx="arch_diagnostic") + operation_type = models.OperationType.objects.get(txt_idx="arch_diagnostic") if not values: values = {} - dct = {'year': 2010, 'operation_type_id': operation_type.pk, - 'history_modifier': user} + dct = { + "year": 2010, + "operation_type_id": operation_type.pk, + "history_modifier": user, + } dct.update(values) if orga: - dct['operator'] = orga - if 'code_patriarche' not in dct: + dct["operator"] = orga + if "code_patriarche" not in dct: idx = 1 while models.Operation.objects.filter(code_patriarche=str(idx)).count(): idx += 1 @@ -1206,36 +1649,39 @@ class OperationInitTest(object): return self.orgas def get_default_orga(self, user=None): - if not hasattr(self, 'orgas') or not self.orgas: + if not hasattr(self, "orgas") or not self.orgas: self.create_orgas(user) return self.orgas[0] def create_towns(self, datas=None): if not datas: datas = {} - default = {'numero_insee': '12345', 'name': 'default_town'} + default = {"numero_insee": "12345", "name": "default_town"} default.update(datas) town = models.Town.objects.create(**default) - if not hasattr(self, 'towns') or not self.towns: + if not hasattr(self, "towns") or not self.towns: self.towns = [] self.towns.append(town) return self.towns def get_default_town(self): - towns = getattr(self, 'towns', None) + towns = getattr(self, "towns", None) if not towns: self.create_towns() return self.towns[0] def create_parcel(self, data=None): - default = {'town': self.get_default_town(), - 'section': 'A', 'parcel_number': '1'} - if not hasattr(self, 'operations'): + default = { + "town": self.get_default_town(), + "section": "A", + "parcel_number": "1", + } + if not hasattr(self, "operations"): self.create_operation() - default['operation'] = self.operations[0] + default["operation"] = self.operations[0] if data: default.update(data) - if not getattr(self, 'parcels', None): + if not getattr(self, "parcels", None): self.parcels = [] self.parcels.append(models.Parcel.objects.create(**default)) return self.parcels @@ -1254,7 +1700,7 @@ class OperationInitTest(object): self.get_default_orga(user) if not user: self.get_default_user() - if not getattr(self, 'operations', None): + if not getattr(self, "operations", None): self.operations = [] self.operations.append(create_operation(user, orga)) return self.operations @@ -1270,19 +1716,19 @@ class OperationInitTest(object): def tearDown(self): # cleanup for further test - if hasattr(self, 'user'): + if hasattr(self, "user"): self.user.delete() self.user = None # all try/except is necessary for bad migrations on main... # should be removed at the next big version - if hasattr(self, 'operations'): + if hasattr(self, "operations"): for ope in self.operations: try: ope.delete() except: pass self.operations = [] - if hasattr(self, 'parcels'): + if hasattr(self, "parcels"): for p in self.parcels: try: p.delete() @@ -1295,93 +1741,105 @@ class OperationTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='view_own_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="view_own_operation") + ) self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) self.operations += self.create_operation(self.alt_user, self.orgas[0]) self.item = self.operations[0] for idx in range(15): - ContextRecord.objects.create(label='CR-{}'.format(idx), - operation=self.item) + ContextRecord.objects.create(label="CR-{}".format(idx), operation=self.item) def test_external_id(self): - self.item.code_patriarche = '123456789' + self.item.code_patriarche = "123456789" self.item.save() parcel = self.get_default_parcel() parcel.operation = self.item parcel.save() correct_ext_id = "{}-{}-{}{}".format( - self.item.code_patriarche, parcel.town.numero_insee, - parcel.section, parcel.parcel_number) + self.item.code_patriarche, + parcel.town.numero_insee, + parcel.section, + parcel.parcel_number, + ) self.assertEqual(parcel.external_id, correct_ext_id) # auto has been previously set - parcel.external_id = 'blabla' + parcel.external_id = "blabla" parcel.save() self.assertEqual(parcel.external_id, correct_ext_id) # deactivate auto parcel.auto_external_id = False - parcel.external_id = 'blabla' + parcel.external_id = "blabla" parcel.save() - self.assertEqual(parcel.external_id, 'blabla') + self.assertEqual(parcel.external_id, "blabla") def test_complete_identifier(self): profile = get_current_profile() - profile.operation_complete_identifier = \ + profile.operation_complete_identifier = ( "{code_patriarche}-{towns__numero_insee}" + ) profile.save() self.item = models.Operation.objects.get(pk=self.item.pk) t = Town.objects.create(numero_insee="12345", name="OK town") self.item.towns.add(t) self.item = models.Operation.objects.get(pk=self.item.pk) - self.item.code_patriarche = '123456789' + self.item.code_patriarche = "123456789" self.item.year = 2020 self.item.save() self.item = models.Operation.objects.get(pk=self.item.pk) - self.assertEqual(self.item.complete_identifier, - '{}-{}'.format(self.item.code_patriarche, - t.numero_insee)) + self.assertEqual( + self.item.complete_identifier, + "{}-{}".format(self.item.code_patriarche, t.numero_insee), + ) - profile.operation_complete_identifier = \ - "{year}-{towns__numero_insee}" + profile.operation_complete_identifier = "{year}-{towns__numero_insee}" profile.save() self.item.save() self.item = models.Operation.objects.get(pk=self.item.pk) - self.assertEqual(self.item.complete_identifier, - '{}-{}'.format(self.item.year, - t.numero_insee)) + self.assertEqual( + self.item.complete_identifier, + "{}-{}".format(self.item.year, t.numero_insee), + ) def test_associated(self): scientist = Person.objects.create(name="C-3PO") self.item.scientist = scientist self.item.save() scientist = Person.objects.get(pk=scientist.pk) - self.assertIn(PersonType.objects.get(txt_idx='head_scientist'), - scientist.person_types.all()) + self.assertIn( + PersonType.objects.get(txt_idx="head_scientist"), + scientist.person_types.all(), + ) # do not change if in the list sra = Person.objects.create(name="R2D2") - sra.person_types.add(PersonType.objects.get(txt_idx='sra_agent')) + sra.person_types.add(PersonType.objects.get(txt_idx="sra_agent")) self.item.scientist = sra self.item.save() - self.assertNotIn(PersonType.objects.get(txt_idx='head_scientist'), - sra.person_types.all()) + self.assertNotIn( + PersonType.objects.get(txt_idx="head_scientist"), sra.person_types.all() + ) def create_relations(self): rel1 = models.RelationType.objects.create( - symmetrical=True, label='Include', txt_idx='include') + symmetrical=True, label="Include", txt_idx="include" + ) rel2 = models.RelationType.objects.create( - symmetrical=False, label='Included', txt_idx='included', - inverse_relation=rel1) + symmetrical=False, + label="Included", + txt_idx="included", + inverse_relation=rel1, + ) models.RecordRelations.objects.create( left_record=self.operations[0], right_record=self.operations[1], - relation_type=rel1) + relation_type=rel1, + ) return rel1, rel2 def testPostDeleteRelations(self): @@ -1390,7 +1848,7 @@ class OperationTest(TestCase, OperationInitTest): def testPostDeleteParcels(self): ope = self.operations[0] - town = Town.objects.create(name='plouf', numero_insee='20000') + town = Town.objects.create(name="plouf", numero_insee="20000") parcel = models.Parcel.objects.create(town=town) parcel_nb = models.Parcel.objects.count() ope.parcels.add(parcel) @@ -1407,38 +1865,37 @@ class OperationTest(TestCase, OperationInitTest): self.assertEqual(parcel_nb, models.Parcel.objects.count()) def testIndex(self): - ope = create_operation(self.user, values={'year': 2042}) + ope = create_operation(self.user, values={"year": 2042}) self.assertEqual(ope.operation_code, 1) - ope2 = create_operation(self.user, values={'year': 2042}) + ope2 = create_operation(self.user, values={"year": 2042}) self.assertEqual(ope2.operation_code, 2) - ope = create_operation(self.user, values={'year': 0}) + ope = create_operation(self.user, values={"year": 0}) self.assertEqual(ope.operation_code, 1) - ope2 = create_operation(self.user, values={'year': 0}) + ope2 = create_operation(self.user, values={"year": 0}) self.assertEqual(ope2.operation_code, 2) def test_cache_update(self): self.create_towns() operation = self.operations[0] self.assertIsNotNone(operation.cached_label) - town, ope_id = operation.cached_label.split(' | ') - self.assertIn(town, ('Intercommunal', "Multi-town")) - self.assertEqual(ope_id, 'OA1 - OP2010-1') + town, ope_id = operation.cached_label.split(" | ") + self.assertIn(town, ("Intercommunal", "Multi-town")) + self.assertEqual(ope_id, "OA1 - OP2010-1") operation = models.Operation.objects.get(pk=operation.pk) operation.year = 2011 operation.save() operation.towns.add(self.towns[0]) operation = models.Operation.objects.get(pk=operation.pk) self.assertIsNotNone(operation.cached_label) - town, ope_id = operation.cached_label.split(' | ') - self.assertEqual(ope_id, 'OA1 - OP2011-1') + town, ope_id = operation.cached_label.split(" | ") + self.assertEqual(ope_id, "OA1 - OP2011-1") self.assertEqual(town, self.towns[0].name) def test_search_vector_update(self): operation = self.operations[0] - town = self.create_towns({'numero_insee': '12346', 'name': 'Daisy'})[-1] + town = self.create_towns({"numero_insee": "12346", "name": "Daisy"})[-1] operation.towns.add(town) - town = self.create_towns( - {'numero_insee': '12347', 'name': 'Dirty old'})[-1] + town = self.create_towns({"numero_insee": "12347", "name": "Dirty old"})[-1] operation.towns.add(town) operation = models.Operation.objects.get(pk=operation.pk) operation.comment = "Zardoz" @@ -1449,9 +1906,15 @@ class OperationTest(TestCase, OperationInitTest): operation.save() self.assertIsNotNone(operation.search_vector) for key in ( - 'old', 'dirty', 'daisy', "'2010'", "zardoz", "huiaaa5", - "{}42huiaaa5".format(profile.operation_prefix.lower()), - "42huiaaa5"): + "old", + "dirty", + "daisy", + "'2010'", + "zardoz", + "huiaaa5", + "{}42huiaaa5".format(profile.operation_prefix.lower()), + "42huiaaa5", + ): self.assertIn(key, operation.search_vector) def test_cache_bulk_update(self): @@ -1460,24 +1923,30 @@ class OperationTest(TestCase, OperationInitTest): operation.parcels.add(init_parcel) from archaeological_context_records.models import ContextRecord - cr_data = {'label': "Context record", "operation": operation, - 'parcel': init_parcel, - 'history_modifier': self.get_default_user()} + + cr_data = { + "label": "Context record", + "operation": operation, + "parcel": init_parcel, + "history_modifier": self.get_default_user(), + } cr = ContextRecord.objects.create(**cr_data) from archaeological_finds.models import BaseFind, Find, MaterialType + bf_data = { - 'label': "Base find", 'history_modifier': self.get_default_user(), - 'context_record': cr + "label": "Base find", + "history_modifier": self.get_default_user(), + "context_record": cr, } base_find = BaseFind.objects.create(**bf_data) find = Find.objects.create( - history_modifier=self.get_default_user(), - label='Find me' + history_modifier=self.get_default_user(), label="Find me" ) find.base_finds.add(base_find) mat = MaterialType.objects.create( - label='Adamentium', txt_idx='admentium', code='ADA') + label="Adamentium", txt_idx="admentium", code="ADA" + ) find.material_types.add(mat) class TestObj(object): @@ -1485,7 +1954,7 @@ class OperationTest(TestCase, OperationInitTest): self.context_record_reached = [] def reached(self, sender, **kwargs): - instance = kwargs.get('instance') + instance = kwargs.get("instance") if sender == ContextRecord: self.context_record_reached.append(instance) @@ -1501,73 +1970,70 @@ class OperationTest(TestCase, OperationInitTest): # verify the relevance of the update cr = ContextRecord.objects.get(pk=cr.pk) self.assertIsNotNone(cr.cached_label) - ope_id, parcel_sec, parcel_nb, cr_label = cr.cached_label.split(' | ') + ope_id, parcel_sec, parcel_nb, cr_label = cr.cached_label.split(" | ") profile = get_current_profile() - self.assertEqual(ope_id, 'OA1') + self.assertEqual(ope_id, "OA1") base_find = BaseFind.objects.get(pk=base_find.pk) - op_code, idx = base_find.cache_short_id.split(' | ') - self.assertEqual(op_code, 'OA1') - self.assertEqual(idx, '00001') + op_code, idx = base_find.cache_short_id.split(" | ") + self.assertEqual(op_code, "OA1") + self.assertEqual(idx, "00001") self.assertIsNotNone(base_find.cache_complete_id) - op_code, mat_code, lbl, idx = base_find.cache_complete_id.split(' | ') - self.assertEqual(op_code, 'OA1') - self.assertEqual(mat_code, 'ADA') - self.assertEqual(lbl, 'Context record') - self.assertEqual(idx, '00001') + op_code, mat_code, lbl, idx = base_find.cache_complete_id.split(" | ") + self.assertEqual(op_code, "OA1") + self.assertEqual(mat_code, "ADA") + self.assertEqual(lbl, "Context record") + self.assertEqual(idx, "00001") find = Find.objects.get(pk=find.pk) self.assertIsNotNone(find.cached_label) - op_code_idx, lbl = find.cached_label.split(' | ') - self.assertEqual(op_code_idx, 'OA1-00001') - self.assertEqual(lbl, 'Find me') + op_code_idx, lbl = find.cached_label.split(" | ") + self.assertEqual(op_code_idx, "OA1-00001") + self.assertEqual(lbl, "Find me") operation = models.Operation.objects.get(pk=operation.pk) - operation.code_patriarche = '666' + operation.code_patriarche = "666" operation.save() cr = ContextRecord.objects.get(pk=cr.pk) self.assertIsNotNone(cr.cached_label) - ope_id, parcel_sec, parcel_nb, cr_label = cr.cached_label.split(' | ') + ope_id, parcel_sec, parcel_nb, cr_label = cr.cached_label.split(" | ") - self.assertEqual(ope_id, '{}666'.format(profile.operation_prefix)) + self.assertEqual(ope_id, "{}666".format(profile.operation_prefix)) base_find = BaseFind.objects.get(pk=base_find.pk) self.assertIsNotNone(base_find.cache_short_id) - op_code, idx = base_find.cache_short_id.split(' | ') - self.assertEqual(op_code, 'OA666') + op_code, idx = base_find.cache_short_id.split(" | ") + self.assertEqual(op_code, "OA666") self.assertIsNotNone(base_find.cache_complete_id) - op_code, mat_code, lbl, idx = base_find.cache_complete_id.split(' | ') - self.assertEqual(op_code, 'OA666') + op_code, mat_code, lbl, idx = base_find.cache_complete_id.split(" | ") + self.assertEqual(op_code, "OA666") find = Find.objects.get(pk=find.pk) self.assertIsNotNone(find.cached_label) - op_code_idx, lbl = find.cached_label.split(' | ') - self.assertEqual(op_code_idx, 'OA666-00001') + op_code_idx, lbl = find.cached_label.split(" | ") + self.assertEqual(op_code_idx, "OA666-00001") def test_show(self): operation = self.operations[0] source = models.Document.objects.create( - title="Source title", - source_type=models.SourceType.objects.all()[0] + title="Source title", source_type=models.SourceType.objects.all()[0] ) operation.documents.add(source) c = Client() - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) # empty content when not allowed self.assertEqual(response.content, b"") - response = c.get(reverse('show-document', - kwargs={'pk': source.pk})) + response = c.get(reverse("show-document", kwargs={"pk": source.pk})) self.assertRedirects(response, "/") c.login(username=self.username, password=self.password) - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) self.assertIn(b'class="card sheet"', response.content) - response = c.get(reverse('show-document', - kwargs={'pk': source.pk})) + response = c.get(reverse("show-document", kwargs={"pk": source.pk})) self.assertEqual(response.status_code, 200) self.assertIn(b'class="card sheet"', response.content) @@ -1582,46 +2048,53 @@ class OperationTest(TestCase, OperationInitTest): operation.save() c.login(username=self.username, password=self.password) - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) self.assertIn(b'class="card sheet"', response.content) - self.assertIn(b'/show-historized-operation/', response.content) + self.assertIn(b"/show-historized-operation/", response.content) c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) self.assertIn(b'class="card sheet"', response.content) - self.assertNotIn(b'/show-historized-operation/', response.content) + self.assertNotIn(b"/show-historized-operation/", response.content) def test_show_pdf(self): operation = self.operations[0] c = Client() - response = c.get(reverse('show-operation', - kwargs={'pk': operation.pk, 'type': 'pdf'})) + response = c.get( + reverse("show-operation", kwargs={"pk": operation.pk, "type": "pdf"}) + ) self.assertEqual(response.status_code, 200) # empty content when not allowed self.assertEqual(response.content, b"") c.login(username=self.username, password=self.password) - response = c.get(reverse('show-operation', - kwargs={'pk': operation.pk, 'type': 'pdf'})) + response = c.get( + reverse("show-operation", kwargs={"pk": operation.pk, "type": "pdf"}) + ) self.assertEqual(response.status_code, 200) f = BytesIO(response.content) - filetype = Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, - stdin=PIPE).communicate(f.read(1024))[0].strip() - self.assertTrue(filetype.startswith(b'application/pdf')) + filetype = ( + Popen("/usr/bin/file -b --mime -", shell=True, stdout=PIPE, stdin=PIPE) + .communicate(f.read(1024))[0] + .strip() + ) + self.assertTrue(filetype.startswith(b"application/pdf")) def test_show_odt(self): - locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8') + locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8") operation = self.operations[0] c = Client() - response = c.get(reverse('show-operation', - kwargs={'pk': operation.pk, 'type': 'odt'})) + response = c.get( + reverse("show-operation", kwargs={"pk": operation.pk, "type": "odt"}) + ) self.assertEqual(response.status_code, 200) # empty content when not allowed self.assertEqual(response.content, b"") c.login(username=self.username, password=self.password) - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk, - 'type': 'odt'})) + response = c.get( + reverse("show-operation", kwargs={"pk": operation.pk, "type": "odt"}) + ) self.assertEqual(response.status_code, 200) f = BytesIO(response.content) z = zipfile.ZipFile(f) @@ -1629,12 +2102,12 @@ class OperationTest(TestCase, OperationInitTest): filename = None for name in z.namelist(): - if name == 'content.xml': + if name == "content.xml": filename = name break self.assertIsNotNone(filename) - tmpdir = tempfile.mkdtemp(prefix='tmp-ishtar-') + tmpdir = tempfile.mkdtemp(prefix="tmp-ishtar-") imported_file = z.extract(filename, tmpdir) with open(imported_file) as content_file: content = content_file.read() @@ -1645,34 +2118,45 @@ class OperationTest(TestCase, OperationInitTest): def test_json(self): operation = self.operations[0] - operation.data = {"groundhog": {"number": 53444, - "awake_state": "réveillée", - "with_feather": "Oui"}, - "frog_number": 32303} + operation.data = { + "groundhog": { + "number": 53444, + "awake_state": "réveillée", + "with_feather": "Oui", + }, + "frog_number": 32303, + } operation.save() content_type = ContentType.objects.get_for_model(operation) groundhog_section = JsonDataSection.objects.create( - name="Marmotte", content_type=content_type) - JsonDataField.objects.create(name="État d'éveil", - key='groundhog__awake_state', - content_type=content_type, - section=groundhog_section) - JsonDataField.objects.create(name="Avec plume", - key='groundhog__with_feather', - content_type=content_type, - section=groundhog_section) - JsonDataField.objects.create(name="Zzzzzzzz", - key='groundhog__zzz', - content_type=content_type, - section=groundhog_section) - JsonDataField.objects.create(name="Grenouille", - key='frog_number', - content_type=content_type) + name="Marmotte", content_type=content_type + ) + JsonDataField.objects.create( + name="État d'éveil", + key="groundhog__awake_state", + content_type=content_type, + section=groundhog_section, + ) + JsonDataField.objects.create( + name="Avec plume", + key="groundhog__with_feather", + content_type=content_type, + section=groundhog_section, + ) + JsonDataField.objects.create( + name="Zzzzzzzz", + key="groundhog__zzz", + content_type=content_type, + section=groundhog_section, + ) + JsonDataField.objects.create( + name="Grenouille", key="frog_number", content_type=content_type + ) c = Client() c.login(username=self.username, password=self.password) - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) content = response.content.decode() self.assertIn('class="card sheet"', content) @@ -1686,7 +2170,7 @@ class OperationTest(TestCase, OperationInitTest): operation.data = {} operation.save() - response = c.get(reverse('show-operation', kwargs={'pk': operation.pk})) + response = c.get(reverse("show-operation", kwargs={"pk": operation.pk})) self.assertEqual(response.status_code, 200) self.assertIn(b'class="card sheet"', response.content) self.assertNotIn(b"Marmotte", response.content) @@ -1694,30 +2178,33 @@ class OperationTest(TestCase, OperationInitTest): def test_json_search_vector_update(self): operation = self.operations[0] content_type = ContentType.objects.get_for_model(operation) - JsonDataField.objects.create(name="Nom de marmotte", - key='groundhog__name', - content_type=content_type, - search_index=True) - JsonDataField.objects.create(name="Numéro grenouille", - key='frog_number', - content_type=content_type) + JsonDataField.objects.create( + name="Nom de marmotte", + key="groundhog__name", + content_type=content_type, + search_index=True, + ) + JsonDataField.objects.create( + name="Numéro grenouille", key="frog_number", content_type=content_type + ) operation = models.Operation.objects.get(pk=operation.pk) - operation.data = {"groundhog": {"name": "La Marmotte héhé", - "color": "Red"}, - "frog_number": 32303} + operation.data = { + "groundhog": {"name": "La Marmotte héhé", "color": "Red"}, + "frog_number": 32303, + } operation.save() operation = models.Operation.objects.get(pk=operation.pk) self.assertIsNotNone(operation.search_vector) - for key in ('marmott',): + for key in ("marmott",): self.assertIn(key, operation.search_vector) - for key in ('32303', 'red', 'Red'): + for key in ("32303", "red", "Red"): self.assertNotIn(key, operation.search_vector) def test_document(self): operation = self.operations[0] - q = Document.objects.values('index').order_by('-index') + q = Document.objects.values("index").order_by("-index") if q.count(): - c_index = q.all()[0]['index'] + c_index = q.all()[0]["index"] else: c_index = 0 doc = Document.objects.create(title="Image!") @@ -1737,23 +2224,19 @@ class OperationTest(TestCase, OperationInitTest): Find = apps.get_model("archaeological_finds", "Find") BaseFind = apps.get_model("archaeological_finds", "BaseFind") Warehouse = apps.get_model("archaeological_warehouse", "Warehouse") - WarehouseType = apps.get_model("archaeological_warehouse", - "WarehouseType") + WarehouseType = apps.get_model("archaeological_warehouse", "WarehouseType") Container = apps.get_model("archaeological_warehouse", "Container") - ContainerType = apps.get_model("archaeological_warehouse", - "ContainerType") + ContainerType = apps.get_model("archaeological_warehouse", "ContainerType") operation = self.operations[0] - hc, __ = Unit.objects.get_or_create(txt_idx='not-in-context', order=10) - cr = ContextRecord.objects.create( - operation=operation, unit=hc) + hc, __ = Unit.objects.get_or_create(txt_idx="not-in-context", order=10) + cr = ContextRecord.objects.create(operation=operation, unit=hc) bf = BaseFind.objects.create(context_record=cr) f = Find.objects.create() f.base_finds.add(bf) - wt = WarehouseType.objects.create(label='WT') + wt = WarehouseType.objects.create(label="WT") w = Warehouse.objects.create(name="Warehouse", warehouse_type=wt) - ct = ContainerType.objects.create(label='CT') - c = Container.objects.create(reference="Test", location=w, - container_type=ct) + ct = ContainerType.objects.create(label="CT") + c = Container.objects.create(reference="Test", location=w, container_type=ct) f.container = c f.save() @@ -1765,8 +2248,7 @@ class LockTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) @@ -1781,39 +2263,39 @@ class LockTest(TestCase, OperationInitTest): cls_wiz = OperationWizardModifTest() url = reverse(cls_wiz.url_name) # first wizard step - step = 'selec-operation_modification' + step = "selec-operation_modification" response = cls_wiz.wizard_post( - self.client, url, step, {'pk': self.operation.pk}) - msg = str(_("This item is locked for edition.") - ).replace("'", "'") - self.assertIn(msg, response.content.decode(), - msg="wizard lock for edition not effective") + self.client, url, step, {"pk": self.operation.pk} + ) + msg = str(_("This item is locked for edition.")).replace("'", "'") + self.assertIn( + msg, response.content.decode(), msg="wizard lock for edition not effective" + ) def test_qa_lock(self): - url = reverse('operation-qa-bulk-update', args=[self.operation.pk]) + url = reverse("operation-qa-bulk-update", args=[self.operation.pk]) response = self.client.get(url) - self.assertRedirects(response, reverse('qa-not-available', - args=["locked"])) + self.assertRedirects(response, reverse("qa-not-available", args=["locked"])) def test_sheet_lock(self): - url = reverse('show-operation', kwargs={'pk': self.operation.pk}) + url = reverse("show-operation", kwargs={"pk": self.operation.pk}) response = self.client.get(url) - msg = str(_("This item has been locked. Edition is disabled.") - ).replace("'", "\'") - self.assertIn(msg, response.content.decode(), - msg="lock not displayed on sheet") + msg = str(_("This item has been locked. Edition is disabled.")).replace( + "'", "'" + ) + self.assertIn(msg, response.content.decode(), msg="lock not displayed on sheet") class CustomFormTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='view_own_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="view_own_operation") + ) self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) self.operations += self.create_operation(self.alt_user, self.orgas[0]) @@ -1826,42 +2308,46 @@ class CustomFormTest(TestCase, OperationInitTest): cls_wiz = OperationWizardModifTest() url = reverse(cls_wiz.url_name) # first wizard step - step = 'selec-operation_modification' - cls_wiz.wizard_post(c, url, step, {'pk': self.operations[0].pk}) + step = "selec-operation_modification" + cls_wiz.wizard_post(c, url, step, {"pk": self.operations[0].pk}) - step = 'general-operation_modification' + step = "general-operation_modification" data = { - '{}{}-current_step'.format(cls_wiz.url_name, - cls_wiz.wizard_name): [step], + "{}{}-current_step".format(cls_wiz.url_name, cls_wiz.wizard_name): [step], } - MSG_FOUND = " - '{}' field found on the modification "\ - "wizard. It should have been filtered." - MSG_NOT_FOUND = " - '{}' field not found on the modification "\ - "wizard. It shouldn't have been filtered." + MSG_FOUND = ( + " - '{}' field found on the modification " + "wizard. It should have been filtered." + ) + MSG_NOT_FOUND = ( + " - '{}' field not found on the modification " + "wizard. It shouldn't have been filtered." + ) key_in_charge = "in_charge" response = c.post(url, data) content = response.content.decode() res = key_in_charge in content - self.assertTrue(res, - msg="filter all" + MSG_NOT_FOUND.format(key_in_charge)) + self.assertTrue(res, msg="filter all" + MSG_NOT_FOUND.format(key_in_charge)) f = CustomForm.objects.create( - name="Test - all", form="operation-010-general", - available=True, apply_to_all=True) + name="Test - all", + form="operation-010-general", + available=True, + apply_to_all=True, + ) ExcludedField.objects.create(custom_form=f, field="in_charge") response = c.post(url, data) content = response.content.decode() res = key_in_charge not in content - self.assertTrue(res, - msg="filter all" + MSG_FOUND.format(key_in_charge)) + self.assertTrue(res, msg="filter all" + MSG_FOUND.format(key_in_charge)) # user type form prevail on "all" f_scientist = CustomForm.objects.create( - name="Test - user type", form="operation-010-general", - available=True) - tpe = PersonType.objects.get(txt_idx='head_scientist') + name="Test - user type", form="operation-010-general", available=True + ) + tpe = PersonType.objects.get(txt_idx="head_scientist") key_address = "address" f_scientist.user_types.add(tpe) self.user.ishtaruser.person.person_types.add(tpe) @@ -1871,60 +2357,53 @@ class CustomFormTest(TestCase, OperationInitTest): content = response.content.decode() res = key_in_charge in content self.assertTrue( - res, - msg="filter profile type" + MSG_NOT_FOUND.format(key_in_charge) + res, msg="filter profile type" + MSG_NOT_FOUND.format(key_in_charge) ) res = key_address not in content - self.assertTrue( - res, - msg="filter profile type" + MSG_FOUND.format(key_address)) + self.assertTrue(res, msg="filter profile type" + MSG_FOUND.format(key_address)) # profile type form prevail on "all" and "user types" f_scientist2 = CustomForm.objects.create( - name="Test - profile type", form="operation-010-general", - available=True) + name="Test - profile type", form="operation-010-general", available=True + ) key_scientific = "scientific_documentation_comment" - ExcludedField.objects.create(custom_form=f_scientist2, - field=key_scientific) + ExcludedField.objects.create(custom_form=f_scientist2, field=key_scientific) - collaborator = ProfileType.objects.get(txt_idx='collaborator') + collaborator = ProfileType.objects.get(txt_idx="collaborator") UserProfile.objects.create( - profile_type=collaborator, - person=self.user.ishtaruser.person, - current=True) + profile_type=collaborator, person=self.user.ishtaruser.person, current=True + ) f_scientist2.profile_types.add(collaborator) response = c.post(url, data) content = response.content.decode() res = key_in_charge in content self.assertTrue( - res, - msg="filter profile type" + MSG_NOT_FOUND.format(key_in_charge)) + res, msg="filter profile type" + MSG_NOT_FOUND.format(key_in_charge) + ) res = key_address in content self.assertTrue( - res, - msg="filter profile type" + MSG_NOT_FOUND.format(key_address)) + res, msg="filter profile type" + MSG_NOT_FOUND.format(key_address) + ) res = key_scientific not in content self.assertTrue( - res, - msg="filter profile type" + MSG_FOUND.format(key_scientific)) + res, msg="filter profile type" + MSG_FOUND.format(key_scientific) + ) # user prevail on "all", "profile_type" and "user_types" f_user = CustomForm.objects.create( - name="Test - user", form="operation-010-general", available=True) + name="Test - user", form="operation-010-general", available=True + ) f_user.users.add(self.user.ishtaruser) response = c.post(url, data) content = response.content.decode() res = key_in_charge in content - self.assertTrue(res, - msg="filter user" + MSG_NOT_FOUND.format(key_in_charge)) + self.assertTrue(res, msg="filter user" + MSG_NOT_FOUND.format(key_in_charge)) res = key_scientific in content - self.assertTrue(res, - msg="filter user" + MSG_NOT_FOUND.format(key_scientific)) + self.assertTrue(res, msg="filter user" + MSG_NOT_FOUND.format(key_scientific)) res = key_address in content - self.assertTrue(res, - msg="filter user" + MSG_FOUND.format(key_address)) + self.assertTrue(res, msg="filter user" + MSG_FOUND.format(key_address)) def test_enabled(self): c = Client() @@ -1933,37 +2412,47 @@ class CustomFormTest(TestCase, OperationInitTest): cls_wiz = OperationWizardModifTest() url = reverse(cls_wiz.url_name) # first wizard step - step = 'selec-operation_modification' - cls_wiz.wizard_post(c, url, step, {'pk': self.operations[0].pk}) + step = "selec-operation_modification" + cls_wiz.wizard_post(c, url, step, {"pk": self.operations[0].pk}) - step = 'collaborators-operation_modification' + step = "collaborators-operation_modification" data = { - '{}{}-current_step'.format(cls_wiz.url_name, - cls_wiz.wizard_name): [step], + "{}{}-current_step".format(cls_wiz.url_name, cls_wiz.wizard_name): [step], } response = c.post(url, data) self.assertNotEqual(response.status_code, 404) CustomForm.objects.create( - name="Test2", form="operation-020-collaborators", available=True, - apply_to_all=True, enabled=False) + name="Test2", + form="operation-020-collaborators", + available=True, + apply_to_all=True, + enabled=False, + ) response = c.post(url, data) self.assertEqual(response.status_code, 404) def test_json(self): operation = self.operations[0] - operation.data = {"groundhog": {"number": 53444, - "awake_state": "réveillée", - "with_feather": "Oui"}, - "frog_number": 32303} + operation.data = { + "groundhog": { + "number": 53444, + "awake_state": "réveillée", + "with_feather": "Oui", + }, + "frog_number": 32303, + } operation.save() content_type = ContentType.objects.get_for_model(operation) field = JsonDataField.objects.create( - name="État d'éveil", key='groundhog__awake_state', - content_type=content_type, value_type='C') + name="État d'éveil", + key="groundhog__awake_state", + content_type=content_type, + value_type="C", + ) form = CustomForm.objects.create( - name="Test", form="operation-010-general", available=True, - apply_to_all=True) + name="Test", form="operation-010-general", available=True, apply_to_all=True + ) CustomFormJsonField.objects.create( custom_form=form, json_field=field, @@ -1976,50 +2465,52 @@ class CustomFormTest(TestCase, OperationInitTest): cls_wiz = OperationWizardModifTest() url = reverse(cls_wiz.url_name) # first wizard step - step = 'selec-operation_modification' - cls_wiz.wizard_post(c, url, step, {'pk': self.operations[0].pk}) + step = "selec-operation_modification" + cls_wiz.wizard_post(c, url, step, {"pk": self.operations[0].pk}) - step = 'general-operation_modification' + step = "general-operation_modification" data = { - '{}{}-current_step'.format(cls_wiz.url_name, - cls_wiz.wizard_name): [step], + "{}{}-current_step".format(cls_wiz.url_name, cls_wiz.wizard_name): [step], } response = c.post(url, data) self.assertIn( - b"Le beau", response.content, - msg="json field not displayed on modification wizard" + b"Le beau", + response.content, + msg="json field not displayed on modification wizard", ) - cls_wiz.wizard_post(c, url, step, {'pk': self.operations[1].pk}) + cls_wiz.wizard_post(c, url, step, {"pk": self.operations[1].pk}) response = c.post(url, data) self.assertIn( - b"Le beau", response.content, - msg="json field form: existing value should be presented in select" + b"Le beau", + response.content, + msg="json field form: existing value should be presented in select", ) class OperationSearchTest(TestCase, OperationInitTest, SearchText): fixtures = FILE_FIXTURES - SEARCH_URL = 'get-operation' + SEARCH_URL = "get-operation" def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='view_own_operation')) - self.alt_user.user_permissions.add(Permission.objects.get( - codename='change_own_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="view_own_operation") + ) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="change_own_operation") + ) self.alt_username2, self.alt_password2, self.alt_user2 = create_user( - username='luke', password='iamyourfather' + username="luke", password="iamyourfather" ) profile = UserProfile.objects.create( - profile_type=ProfileType.objects.get(txt_idx='collaborator'), - person=self.alt_user2.ishtaruser.person + profile_type=ProfileType.objects.get(txt_idx="collaborator"), + person=self.alt_user2.ishtaruser.person, ) - town = Town.objects.create(name='Tatouine', numero_insee='66000') - area = Area.objects.create(label='Galaxie', txt_idx='galaxie') + town = Town.objects.create(name="Tatouine", numero_insee="66000") + area = Area.objects.create(label="Galaxie", txt_idx="galaxie") area.towns.add(town) profile.areas.add(area) @@ -2033,23 +2524,22 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): def test_base_search(self): c = Client() - response = c.get(reverse('get-operation'), {'year': '2010'}) + response = c.get(reverse("get-operation"), {"year": "2010"}) # no result when no authentication self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) - response = c.get(reverse('get-operation'), {'year': '2010'}) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 2) + response = c.get(reverse("get-operation"), {"year": "2010"}) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 2) response = c.get( - reverse('get-operation'), - {pgettext_lazy("key for text search", "operator"): - self.orgas[0].name}) + reverse("get-operation"), + {pgettext_lazy("key for text search", "operator"): self.orgas[0].name}, + ) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 3) + self.assertEqual(result["recordsTotal"], 3) def test_base_search_vector(self): c = Client() - response = c.get(reverse('get-operation'), {'search_vector': 'chaTEAU'}) + response = c.get(reverse("get-operation"), {"search_vector": "chaTEAU"}) # no result when no authentication self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) @@ -2057,17 +2547,16 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): operation = models.Operation.objects.get(pk=self.operations[0].pk) operation.common_name = "Opération : Château de Fougères" operation.save() - response = c.get(reverse('get-operation'), {'search_vector': 'chaTEAU'}) + response = c.get(reverse("get-operation"), {"search_vector": "chaTEAU"}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) - response = c.get(reverse('get-operation'), {'search_vector': 'château'}) + self.assertEqual(result["recordsTotal"], 1) + response = c.get(reverse("get-operation"), {"search_vector": "château"}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) # test search with inappropriate minus sign - response = c.get(reverse('get-operation'), - {'search_vector': 'chaTEAU - '}) + response = c.get(reverse("get-operation"), {"search_vector": "chaTEAU - "}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) def test_complex_search_vector(self): c = Client() @@ -2077,33 +2566,34 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): operation_3 = models.Operation.objects.get(pk=self.operations[2].pk) operation_1.common_name = "Opération : Château de Fougères" operation_1.save() - operation_2.common_name = "Opération : Fougère filicophyta et " \ - "herbe à chat" + operation_2.common_name = "Opération : Fougère filicophyta et " "herbe à chat" operation_2.save() operation_3.common_name = "Opération : Château Filicophyta" operation_3.save() # simple separation - response = c.get(reverse('get-operation'), - {'search_vector': 'chaTEAU fougeres'}) + response = c.get( + reverse("get-operation"), {"search_vector": "chaTEAU fougeres"} + ) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) - response = c.get(reverse('get-operation'), - {'search_vector': 'chaTEAU fougere'}) + self.assertEqual(result["recordsTotal"], 1) + response = c.get(reverse("get-operation"), {"search_vector": "chaTEAU fougere"}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) # explicit AND - response = c.get(reverse('get-operation'), - {'search_vector': 'chaTEAU & fougere'}) + response = c.get( + reverse("get-operation"), {"search_vector": "chaTEAU & fougere"} + ) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) # explicit OR - response = c.get(reverse('get-operation'), - {'search_vector': 'chaTEAU | fougere'}) + response = c.get( + reverse("get-operation"), {"search_vector": "chaTEAU | fougere"} + ) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 3) + self.assertEqual(result["recordsTotal"], 3) # query with parenthesis # response = c.get(reverse('get-operation'), @@ -2112,21 +2602,22 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): # self.assertEqual(result['recordsTotal'], 2) # query with mistmatch parenthesis - response = c.get(reverse('get-operation'), - {'search_vector': ')) 2010 &) ((chaTEAU | fougere)'}) + response = c.get( + reverse("get-operation"), + {"search_vector": ")) 2010 &) ((chaTEAU | fougere)"}, + ) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 2) + self.assertEqual(result["recordsTotal"], 2) # open search - response = c.get(reverse('get-operation'), {'search_vector': 'cha*'}) + response = c.get(reverse("get-operation"), {"search_vector": "cha*"}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 3) + self.assertEqual(result["recordsTotal"], 3) # exclude - response = c.get(reverse('get-operation'), - {'search_vector': '-fougere'}) + response = c.get(reverse("get-operation"), {"search_vector": "-fougere"}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) def test_facet_search_vector(self): ope1 = self.operations[0] @@ -2141,13 +2632,13 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): ope2.year = 2020 ope2.save() - data = {'numero_insee': '05000', 'name': 'Champoleon (test)'} + data = {"numero_insee": "05000", "name": "Champoleon (test)"} town = self.create_towns(datas=data)[-1] ope1.towns.add(town) - neo = models.Period.objects.get(txt_idx='neolithic') - final_neo = models.Period.objects.get(txt_idx='final-neolithic') + neo = models.Period.objects.get(txt_idx="neolithic") + final_neo = models.Period.objects.get(txt_idx="final-neolithic") gallo = models.Period.objects.get(txt_idx="gallo-roman") ope1.periods.add(final_neo) @@ -2155,7 +2646,7 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): ope2.periods.add(neo) ope3.periods.add(gallo) - villa = models.RemainType.objects.get(txt_idx='villa') + villa = models.RemainType.objects.get(txt_idx="villa") ope1.remains.add(villa) search_period_q = str(pgettext("key for text search", "period")) @@ -2180,8 +2671,7 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): result = [ ('{}="{}"'.format(search_town_q, town.cached_label), 1), ] - self._test_search(c, result, - context="String search with parenthesis and minus") + self._test_search(c, result, context="String search with parenthesis and minus") result = [ ('{}="{}"'.format(search_period_q, str(neo)), 2), ] @@ -2193,10 +2683,18 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): self._test_search(c, result, context="Period exclude") result = [ - ('{}="{}"'.format(search_period_q, - '{}";"{}'.format(neo.label, gallo.label)), 3), - ('{}="{}" {}="{}"'.format(search_period_q, neo.label, - search_period_q, gallo.label), 3), + ( + '{}="{}"'.format( + search_period_q, '{}";"{}'.format(neo.label, gallo.label) + ), + 3, + ), + ( + '{}="{}" {}="{}"'.format( + search_period_q, neo.label, search_period_q, gallo.label + ), + 3, + ), ] self._test_search(c, result, context="Period OR") @@ -2215,8 +2713,7 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): result = [ ('{}="{}"'.format(search_remain_q, str(villa)), 1), ] - self._test_search(c, result, - context="Non hierarchic remain search") + self._test_search(c, result, context="Non hierarchic remain search") # boolean search search_open_q = str(pgettext("key for text search", "is-open")) @@ -2236,20 +2733,25 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): search_year_q = str(pgettext("key for text search", "year")) q = '"chateau fougere" {}="2042"'.format(search_year_q) - response = c.get(reverse('get-operation'), {'search_vector': q}) + response = c.get(reverse("get-operation"), {"search_vector": q}) result = json.loads(response.content.decode()) - self.assertEqual(result['recordsTotal'], 1) + self.assertEqual(result["recordsTotal"], 1) def create_relations(self): rel1 = models.RelationType.objects.create( - symmetrical=True, label='Include', txt_idx='include') + symmetrical=True, label="Include", txt_idx="include" + ) rel2 = models.RelationType.objects.create( - symmetrical=False, label='Included', txt_idx='included', - inverse_relation=rel1) + symmetrical=False, + label="Included", + txt_idx="included", + inverse_relation=rel1, + ) models.RecordRelations.objects.create( left_record=self.operations[0], right_record=self.operations[1], - relation_type=rel1) + relation_type=rel1, + ) return rel1, rel2 def test_related_search(self): @@ -2258,17 +2760,13 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): self.operations[1].year = 2011 self.operations[1].save() reltype_key = pgettext_lazy("key for text search", "relation-types") - search = { - 'search_vector': 'year=2010 {}="{}"'.format( - reltype_key, rel2.name) - } - response = c.get(reverse('get-operation'), search) + search = {"search_vector": 'year=2010 {}="{}"'.format(reltype_key, rel2.name)} + response = c.get(reverse("get-operation"), search) # no result when no authentication self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) - response = c.get(reverse('get-operation'), search) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 2) + response = c.get(reverse("get-operation"), search) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 2) def test_search_with_problematic_characters(self): c = Client() @@ -2281,63 +2779,59 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): result = [ ('{}="{}"'.format(search_name_q, lbl), 1), ] - self._test_search(c, result, - context="Facet search with = and | characters") + self._test_search(c, result, context="Facet search with = and | characters") def test_search_with_asterisk_inside_names(self): c = Client() c.login(username=self.username, password=self.password) ope = self.operations[0] ope_type = ope.operation_type - ope_type.label = 'label*with*asterisk' + ope_type.label = "label*with*asterisk" ope_type.save() search_name_q = str(pgettext("key for text search", "type")) nb = models.Operation.objects.filter(operation_type=ope_type).count() result = [ ('{}="{}"'.format(search_name_q, ope_type.label), nb), ] - self._test_search(c, result, - context="Facet search with * characters") + self._test_search(c, result, context="Facet search with * characters") def test_hierarchic_search(self): ope = self.operations[1] c = Client() - neo = models.Period.objects.get(txt_idx='neolithic') - final_neo = models.Period.objects.get(txt_idx='final-neolithic') - recent_neo = models.Period.objects.get(txt_idx='recent-neolithic') + neo = models.Period.objects.get(txt_idx="neolithic") + final_neo = models.Period.objects.get(txt_idx="final-neolithic") + recent_neo = models.Period.objects.get(txt_idx="recent-neolithic") ope.periods.add(final_neo) - search = {'periods': final_neo.pk} + search = {"periods": final_neo.pk} # no result when no authentication - response = c.get(reverse('get-operation'), search) + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) # one result for exact search - response = c.get(reverse('get-operation'), search) + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) res = json.loads(response.content.decode()) - self.assertTrue(res['recordsTotal'] == 1) + self.assertTrue(res["recordsTotal"] == 1) # no result for the brother - search = {'periods': recent_neo.pk} - response = c.get(reverse('get-operation'), search) + search = {"periods": recent_neo.pk} + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 0) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 0) # one result for the father - search = {'periods': neo.pk} - response = c.get(reverse('get-operation'), search) + search = {"periods": neo.pk} + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) # test on text search - period_key = str(pgettext_lazy("key for text search", 'period')) + period_key = str(pgettext_lazy("key for text search", "period")) result = [ ('{}="{}"'.format(period_key, str(final_neo)), 1), ('{}="{}"'.format(period_key, str(recent_neo)), 0), @@ -2349,14 +2843,14 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): c = Client() c.login(username=self.username, password=self.password) - data = {'numero_insee': '98989', 'name': 'base_town'} + data = {"numero_insee": "98989", "name": "base_town"} base_town = self.create_towns(datas=data)[-1] - data = {'numero_insee': '56789', 'name': 'parent_town'} + data = {"numero_insee": "56789", "name": "parent_town"} parent_town = self.create_towns(datas=data)[-1] parent_town.children.add(base_town) - data = {'numero_insee': '01234', 'name': 'child_town'} + data = {"numero_insee": "01234", "name": "child_town"} child_town = self.create_towns(datas=data)[-1] base_town.children.add(child_town) @@ -2364,32 +2858,28 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): ope.towns.add(base_town) # simple search - search = {'towns': base_town.pk} - response = c.get(reverse('get-operation'), search) + search = {"towns": base_town.pk} + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) # parent search - search = {'towns': parent_town.pk} - response = c.get(reverse('get-operation'), search) + search = {"towns": parent_town.pk} + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) # child search - search = {'towns': child_town.pk} - response = c.get(reverse('get-operation'), search) + search = {"towns": child_town.pk} + response = c.get(reverse("get-operation"), search) self.assertEqual(response.status_code, 200) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) def test_statistics(self): c = Client() c.login(username=self.username, password=self.password) - q = {"stats_modality_1": "year", - "stats_modality_2": "operation_type__label"} - response = c.get(reverse('get-operation', args=['json-stats']), q) + q = {"stats_modality_1": "year", "stats_modality_2": "operation_type__label"} + response = c.get(reverse("get-operation", args=["json-stats"]), q) self.assertEqual(response.status_code, 200) expected_result = [] @@ -2411,32 +2901,33 @@ class OperationSearchTest(TestCase, OperationInitTest, SearchText): current_values[val_idx][1] += 1 values = json.loads(response.content.decode()) - self.assertEqual(values['data'], expected_result) + self.assertEqual(values["data"], expected_result) class OperationPermissionTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='view_own_operation')) - self.alt_user.user_permissions.add(Permission.objects.get( - codename='change_own_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="view_own_operation") + ) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="change_own_operation") + ) self.alt_username2, self.alt_password2, self.alt_user2 = create_user( - username='luke', password='iamyourfather' + username="luke", password="iamyourfather" ) - profile_type = ProfileType.objects.get(txt_idx='collaborator') + profile_type = ProfileType.objects.get(txt_idx="collaborator") profile = UserProfile.objects.create( profile_type=profile_type, person=self.alt_user2.ishtaruser.person, - current=True + current=True, ) - town = Town.objects.create(name='Tatouine', numero_insee='66000') - area = Area.objects.create(label='Galaxie', txt_idx='galaxie') + town = Town.objects.create(name="Tatouine", numero_insee="66000") + area = Area.objects.create(label="Galaxie", txt_idx="galaxie") area.towns.add(town) profile.areas.add(area) @@ -2449,86 +2940,76 @@ class OperationPermissionTest(TestCase, OperationInitTest): def test_own_search(self): # no result when no authentification c = Client() - response = c.get(reverse('get-operation'), {'year': '2010'}) + response = c.get(reverse("get-operation"), {"year": "2010"}) self.assertTrue(not json.loads(response.content.decode())) # possession c = Client() c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('get-operation'), {'year': '2010'}) + response = c.get(reverse("get-operation"), {"year": "2010"}) # only one "own" operation available self.assertTrue(json.loads(response.content.decode())) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) operator_key = pgettext_lazy("key for text search", "operator") - response = c.get(reverse('get-operation'), - {operator_key: self.orgas[0].name}) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) - response = c.get(reverse('get-operation'), - {'search_vector': '{}="{}"'.format( - operator_key, self.orgas[0].name)}) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + response = c.get(reverse("get-operation"), {operator_key: self.orgas[0].name}) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) + response = c.get( + reverse("get-operation"), + {"search_vector": '{}="{}"'.format(operator_key, self.orgas[0].name)}, + ) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) # area filter c = Client() c.login(username=self.alt_username2, password=self.alt_password2) - response = c.get(reverse('get-operation'), - {'year': '2010'}) + response = c.get(reverse("get-operation"), {"year": "2010"}) # only one "own" operation available self.assertTrue(json.loads(response.content.decode())) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) - response = c.get(reverse('get-operation'), - {operator_key: self.orgas[0].name}) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) - response = c.get(reverse('get-operation'), - {'search_vector': '{}="{}"'.format( - operator_key, self.orgas[0].name)}) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) + response = c.get(reverse("get-operation"), {operator_key: self.orgas[0].name}) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) + response = c.get( + reverse("get-operation"), + {"search_vector": '{}="{}"'.format(operator_key, self.orgas[0].name)}, + ) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) def test_own_modify(self): operation_pk1 = self.operations[0].pk operation_pk2 = self.operations[1].pk - modif_url = '/operation_modification/general-operation_modification' + modif_url = "/operation_modification/general-operation_modification" # no result when no authentification c = Client() - response = c.get(reverse('operation_modify', args=[operation_pk2])) + response = c.get(reverse("operation_modify", args=[operation_pk2])) self.assertRedirects(response, "/") # possession c = Client() c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('operation_modify', args=[operation_pk2]), - follow=True) + response = c.get(reverse("operation_modify", args=[operation_pk2]), follow=True) self.assertRedirects(response, modif_url) response = c.get(modif_url) self.assertEqual(response.status_code, 200) - response = c.get(reverse('operation_modify', args=[operation_pk1]), - follow=True) + response = c.get(reverse("operation_modify", args=[operation_pk1]), follow=True) self.assertRedirects(response, "/") - profile_type = ProfileType.objects.get(txt_idx='collaborator') + profile_type = ProfileType.objects.get(txt_idx="collaborator") profile_type.groups.add( - Group.objects.get(name="Opérations rattachées : " - "modification/suppression") + Group.objects.get( + name="Opérations rattachées : " "modification/suppression" + ) ) # area filter c = Client() c.login(username=self.alt_username2, password=self.alt_password2) - response = c.get(reverse('operation_modify', args=[operation_pk2]), - follow=True) + response = c.get(reverse("operation_modify", args=[operation_pk2]), follow=True) self.assertRedirects(response, modif_url) response = c.get(modif_url) self.assertEqual(response.status_code, 200) - response = c.get(reverse('operation_modify', args=[operation_pk1]), - follow=True) + response = c.get(reverse("operation_modify", args=[operation_pk1]), follow=True) self.assertRedirects(response, "/") @@ -2536,8 +3017,7 @@ class LabelTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) @@ -2548,12 +3028,11 @@ class LabelTest(TestCase, OperationInitTest): ope.save() tpl = open( - settings.ROOT_PATH + - '../archaeological_operations/tests/labels-8.odt', - 'rb') + settings.ROOT_PATH + "../archaeological_operations/tests/labels-8.odt", "rb" + ) template = SimpleUploadedFile(tpl.name, tpl.read()) model, __ = ImporterModel.objects.get_or_create( - klass='archaeological_operations.models.Operation' + klass="archaeological_operations.models.Operation" ) doc = DocumentTemplate.objects.create( name="Labels", @@ -2562,7 +3041,7 @@ class LabelTest(TestCase, OperationInitTest): available=True, for_labels=True, label_per_page=8, - template=template + template=template, ) c = Client() url = reverse("generate-labels", args=[doc.slug]) @@ -2577,9 +3056,9 @@ class LabelTest(TestCase, OperationInitTest): f = BytesIO(response.content) z = zipfile.ZipFile(f) self.assertIsNone(z.testzip()) - content = z.open('content.xml') + content = z.open("content.xml") full_content = content.read() - self.assertIn(b'1789', full_content) + self.assertIn(b"1789", full_content) # jpe file are added for missing pictures / must be filtered self.assertNotIn(b'.jpe"', full_content) finally: @@ -2595,14 +3074,13 @@ class DashboardTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) def test_dashboard(self): - url = 'dashboard-operation' + url = "dashboard-operation" c = Client() c.login(username=self.username, password=self.password) @@ -2612,12 +3090,15 @@ class DashboardTest(TestCase, OperationInitTest): def create_administrativact(user, operation): act_type, created = models.ActType.objects.get_or_create( - txt_idx='act_type_O', intented_to='O') - dct = {'history_modifier': user, - 'act_type': act_type, - 'operation': operation, - 'signature_date': datetime.date(2014, 5, 12), - 'index': 322} + txt_idx="act_type_O", intented_to="O" + ) + dct = { + "history_modifier": user, + "act_type": act_type, + "operation": operation, + "signature_date": datetime.date(2014, 5, 12), + "index": 322, + } adminact, created = models.AdministrativeAct.objects.get_or_create(**dct) return [act_type], [adminact] @@ -2629,53 +3110,53 @@ class RegisterTest(TestCase, OperationInitTest): self.username, self.password, self.user = create_superuser() self.operations = self.create_operation(self.user) self.act_types, self.admin_acts = create_administrativact( - self.user, self.operations[0]) + self.user, self.operations[0] + ) def test_search(self): c = Client() - response = c.get(reverse('get-administrativeact'), {'year': '2014'}) + response = c.get(reverse("get-administrativeact"), {"year": "2014"}) # no result when no authentication self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) - response = c.get(reverse('get-administrativeact'), {'year': '2014'}) - self.assertEqual( - json.loads(response.content.decode())['recordsTotal'], 1) - response = c.get(reverse('get-administrativeact'), {'indexed': '2'}) - self.assertEqual( - json.loads(response.content.decode())['recordsTotal'], 1) + response = c.get(reverse("get-administrativeact"), {"year": "2014"}) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) + response = c.get(reverse("get-administrativeact"), {"indexed": "2"}) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) def test_document_generation(self): tpl = open( - settings.ROOT_PATH + - '../archaeological_operations/tests/document_reference.odt', - 'rb') + settings.ROOT_PATH + + "../archaeological_operations/tests/document_reference.odt", + "rb", + ) template = SimpleUploadedFile(tpl.name, tpl.read()) model, __ = ImporterModel.objects.get_or_create( - klass='archaeological_operations.models.AdministrativeAct' + klass="archaeological_operations.models.AdministrativeAct" ) doc = DocumentTemplate.objects.create( name="Test", slug=True, associated_model=model, available=True, - template=template + template=template, ) self.act_types[0].associated_template.add(doc) c = Client() - data = {'pk': self.admin_acts[0].pk, 'document_template': doc.pk} - response = c.post(reverse('operation-administrativeact-document'), data) + data = {"pk": self.admin_acts[0].pk, "document_template": doc.pk} + response = c.post(reverse("operation-administrativeact-document"), data) # no result when no authentication self.assertEqual(response.content, b"") c.login(username=self.username, password=self.password) - response = c.post(reverse('operation-administrativeact-document'), data) + response = c.post(reverse("operation-administrativeact-document"), data) content, z, f = None, None, None try: f = BytesIO(response.content) z = zipfile.ZipFile(f) self.assertIsNone(z.testzip()) - content = z.open('content.xml') - self.assertIn(b'2014-05-12', content.read()) + content = z.open("content.xml") + self.assertIn(b"2014-05-12", content.read()) finally: if content: content.close() @@ -2687,204 +3168,209 @@ class RegisterTest(TestCase, OperationInitTest): class OperationWizardCreationTest(WizardTest, OperationInitTest, TestCase): fixtures = FILE_FIXTURES - url_name = 'operation_creation' - wizard_name = 'operation_wizard' + url_name = "operation_creation" + wizard_name = "operation_wizard" steps = views.wizard_steps - redirect_url = "/operation_modification/selec-operation_modification"\ - "?open_item={last_id}" + redirect_url = ( + "/operation_modification/selec-operation_modification" "?open_item={last_id}" + ) model = models.Operation form_datas = [ FormData( "Create a preventive diag", form_datas={ - 'filechoice': {}, - 'general': { - 'code_patriarche': 'codeope1', - 'operation_type': None, - 'year': 2016}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "filechoice": {}, + "general": { + "code_patriarche": "codeope1", + "operation_type": None, + "year": 2016, + }, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=('towns-operation_creation', - 'parcels-operation_creation', - 'judiciary-operation_creation', - 'preventive-operation_creation') + ignored=( + "towns-operation_creation", + "parcels-operation_creation", + "judiciary-operation_creation", + "preventive-operation_creation", + ), ), FormData( "Create another preventive diag with same parcel name", form_datas={ - 'filechoice': {}, - 'general': { - 'code_patriarche': 'codeope2', - 'operation_type': None, - 'year': 2016}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "filechoice": {}, + "general": { + "code_patriarche": "codeope2", + "operation_type": None, + "year": 2016, + }, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=('towns-operation_creation', - 'parcels-operation_creation', - 'judiciary-operation_creation', - 'preventive-operation_creation') + ignored=( + "towns-operation_creation", + "parcels-operation_creation", + "judiciary-operation_creation", + "preventive-operation_creation", + ), ), FormData( "Create an operation related to a file", form_datas={ - 'filechoice': {}, - 'general': { - 'code_patriarche': 'codeope3', - 'operation_type': None, - 'year': 2016}, - 'towns': [], - 'parcels': [], + "filechoice": {}, + "general": { + "code_patriarche": "codeope3", + "operation_type": None, + "year": 2016, + }, + "towns": [], + "parcels": [], }, - ignored=('townsgeneral-operation_creation', - 'parcelsgeneral-operation_creation', - 'judiciary-operation_creation', - 'preventive-operation_creation') + ignored=( + "townsgeneral-operation_creation", + "parcelsgeneral-operation_creation", + "judiciary-operation_creation", + "preventive-operation_creation", + ), ), ] def pre_wizard(self): profile, created = IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + slug="default", active=True + ) profile.files = True profile.save() - if 'townsgeneral' not in \ - self.form_datas[0].form_datas: + if "townsgeneral" not in self.form_datas[0].form_datas: return super(OperationWizardCreationTest, self).pre_wizard() town = self.create_towns()[0] - town_data = {'town': town.pk} + town_data = {"town": town.pk} parcel_data = { - 'town': town.pk, 'year': 2017, 'section': 'S', - 'parcel_number': '42'} + "town": town.pk, + "year": 2017, + "section": "S", + "parcel_number": "42", + } for idx in range(2): - self.form_datas[idx].append('townsgeneral', town_data) - self.form_datas[idx].append('parcelsgeneral', parcel_data) + self.form_datas[idx].append("townsgeneral", town_data) + self.form_datas[idx].append("parcelsgeneral", parcel_data) FI = FileInit() FI.create_file() file = FI.item file.towns.add(town) parcel = models.Parcel.objects.create( - town=town, year=2017, section='G', parcel_number='43' + town=town, year=2017, section="G", parcel_number="43" ) file.parcels.add(parcel) - self.form_datas[2].set('filechoice', 'associated_file', file.pk) - self.form_datas[2].append('parcelsgeneral', {'parcel': parcel.pk}) - self.form_datas[2].append('towns', town_data) - self.form_datas[2].append('parcels', {'parcel': parcel.pk}) + self.form_datas[2].set("filechoice", "associated_file", file.pk) + self.form_datas[2].append("parcelsgeneral", {"parcel": parcel.pk}) + self.form_datas[2].append("towns", town_data) + self.form_datas[2].append("parcels", {"parcel": parcel.pk}) # diagnostic - ope_type = models.OperationType.objects.get(txt_idx='arch_diagnostic') - self.form_datas[0].set('general', 'operation_type', ope_type.pk) - self.form_datas[1].set('general', 'operation_type', ope_type.pk) - self.form_datas[2].set('general', 'operation_type', ope_type.pk) + ope_type = models.OperationType.objects.get(txt_idx="arch_diagnostic") + self.form_datas[0].set("general", "operation_type", ope_type.pk) + self.form_datas[1].set("general", "operation_type", ope_type.pk) + self.form_datas[2].set("general", "operation_type", ope_type.pk) self.operation_number = models.Operation.objects.count() self.parcel_number = models.Parcel.objects.count() super(OperationWizardCreationTest, self).pre_wizard() def post_wizard(self): - self.assertEqual(models.Operation.objects.count(), - self.operation_number + 3) + self.assertEqual(models.Operation.objects.count(), self.operation_number + 3) operations = models.Operation.objects.order_by("-pk").all()[:3] parcel_ids = [] for operation in operations: for parcel in operation.parcels.all(): parcel_ids.append(parcel.external_id) - self.assertEqual(list(sorted(parcel_ids)), - ['codeope1-12345-S42', 'codeope2-12345-S42', - 'codeope3-12345-G43']) - self.assertEqual(models.Parcel.objects.count(), - self.parcel_number + 3) + self.assertEqual( + list(sorted(parcel_ids)), + ["codeope1-12345-S42", "codeope2-12345-S42", "codeope3-12345-G43"], + ) + self.assertEqual(models.Parcel.objects.count(), self.parcel_number + 3) class OperationWizardModifTest(WizardTest, OperationInitTest, TestCase): fixtures = FILE_FIXTURES - url_name = 'operation_modification' - wizard_name = url_name + '_wizard' + url_name = "operation_modification" + wizard_name = url_name + "_wizard" steps = views.operation_modif_wizard_steps redirect_url = "/{url_name}/selec-{url_name}?open_item={current_id}" model = models.Operation base_ignored_steps = ( - 'archaeologicalsite-operation_modification', - 'preventive-operation_modification', - 'preventivediag-operation_modification', - 'judiciary-operation_modification', - 'towns-operation_modification', - 'parcels-operation_modification', - 'remains-operation_modification', - 'periods-operation_modification', - 'relations-operation_modification', - 'abstract-operation_modification',) + "archaeologicalsite-operation_modification", + "preventive-operation_modification", + "preventivediag-operation_modification", + "judiciary-operation_modification", + "towns-operation_modification", + "parcels-operation_modification", + "remains-operation_modification", + "periods-operation_modification", + "relations-operation_modification", + "abstract-operation_modification", + ) form_datas = [ FormData( "Update an operation", form_datas={ - 'selec': {}, - 'general': { - 'operation_type': 2, - 'year': 2017}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "selec": {}, + "general": {"operation_type": 2, "year": 2017}, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=base_ignored_steps + ignored=base_ignored_steps, ), FormData( "Operation: try to remove a parcel with attached context record", form_datas={ - 'selec': {}, - 'general': { - 'code_patriarche': "codeope42", - 'operation_type': 2, - 'year': 2017}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "selec": {}, + "general": { + "code_patriarche": "codeope42", + "operation_type": 2, + "year": 2017, + }, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=base_ignored_steps + ignored=base_ignored_steps, ), FormData( "Operation: remove a parcel with no attached context record", form_datas={ - 'selec': {}, - 'general': { - 'operation_type': 2, - 'year': 2017}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "selec": {}, + "general": {"operation_type": 2, "year": 2017}, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=base_ignored_steps + ignored=base_ignored_steps, ), FormData( "Set an operation to an exiting operation code for this year", form_datas={ - 'selec': {}, - 'general': { - 'operation_type': 2, - 'operation_code': 42, - 'year': 2017}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "selec": {}, + "general": {"operation_type": 2, "operation_code": 42, "year": 2017}, + "townsgeneral": [], + "parcelsgeneral": [], }, ignored=base_ignored_steps, - error_expected='general' + error_expected="general", ), FormData( "Operation: change a parcel", form_datas={ - 'selec': {}, - 'general': { - 'operation_type': 2, - 'year': 2017}, - 'townsgeneral': [], - 'parcelsgeneral': [], + "selec": {}, + "general": {"operation_type": 2, "year": 2017}, + "townsgeneral": [], + "parcelsgeneral": [], }, - ignored=base_ignored_steps + ignored=base_ignored_steps, ), ] @@ -2903,19 +3389,22 @@ class OperationWizardModifTest(WizardTest, OperationInitTest, TestCase): operation2.save() from archaeological_context_records.models import ContextRecord - cr_data = {'label': "Context record", "operation": operation, - 'parcel': init_parcel, - 'history_modifier': self.get_default_user()} + + cr_data = { + "label": "Context record", + "operation": operation, + "parcel": init_parcel, + "history_modifier": self.get_default_user(), + } self.cr = ContextRecord.objects.create(**cr_data) # diagnostic - self.ope_type = models.OperationType.objects.get( - txt_idx='prev_excavation') - self.form_datas[0].set('general', 'operation_type', self.ope_type.pk) - self.form_datas[1].set('general', 'operation_type', self.ope_type.pk) - self.form_datas[2].set('general', 'operation_type', self.ope_type.pk) - self.form_datas[3].set('general', 'operation_type', self.ope_type.pk) - self.form_datas[4].set('general', 'operation_type', self.ope_type.pk) + self.ope_type = models.OperationType.objects.get(txt_idx="prev_excavation") + self.form_datas[0].set("general", "operation_type", self.ope_type.pk) + self.form_datas[1].set("general", "operation_type", self.ope_type.pk) + self.form_datas[2].set("general", "operation_type", self.ope_type.pk) + self.form_datas[3].set("general", "operation_type", self.ope_type.pk) + self.form_datas[4].set("general", "operation_type", self.ope_type.pk) data = self.form_datas[0].form_datas data2 = self.form_datas[1].form_datas @@ -2923,116 +3412,124 @@ class OperationWizardModifTest(WizardTest, OperationInitTest, TestCase): data4 = self.form_datas[3].form_datas data5 = self.form_datas[4].form_datas - data['selec']['pk'] = operation.pk - data2['selec']['pk'] = operation.pk - data3['selec']['pk'] = operation.pk - data4['selec']['pk'] = operation.pk - data5['selec']['pk'] = operation.pk + data["selec"]["pk"] = operation.pk + data2["selec"]["pk"] = operation.pk + data3["selec"]["pk"] = operation.pk + data4["selec"]["pk"] = operation.pk + data5["selec"]["pk"] = operation.pk - town = self.create_towns( - datas={'numero_insee': '67890', 'name': 'Twin Peaks'})[-1] - towns = [{'town': town.pk}, {'town': init_town.pk}] + town = self.create_towns(datas={"numero_insee": "67890", "name": "Twin Peaks"})[ + -1 + ] + towns = [{"town": town.pk}, {"town": init_town.pk}] parcel_data = { - 'town': town.pk, 'year': 2017, 'section': 'S', - 'parcel_number': '42'} + "town": town.pk, + "year": 2017, + "section": "S", + "parcel_number": "42", + } for idx in range(0, 5): for t in towns: - self.form_datas[idx].append('townsgeneral', t) + self.form_datas[idx].append("townsgeneral", t) if idx != 4: - self.form_datas[idx].append('parcelsgeneral', parcel_data) + self.form_datas[idx].append("parcelsgeneral", parcel_data) parcel_data_2 = { - 'town': init_parcel.town.pk, 'year': init_parcel.year or '', - 'section': init_parcel.section, - 'pk': init_parcel.pk, - 'parcel_number': init_parcel.parcel_number} - data['parcelsgeneral'].append(parcel_data_2) + "town": init_parcel.town.pk, + "year": init_parcel.year or "", + "section": init_parcel.section, + "pk": init_parcel.pk, + "parcel_number": init_parcel.parcel_number, + } + data["parcelsgeneral"].append(parcel_data_2) p = parcel_data.copy() - p['parcel_number'] = '43' - self.form_datas[4].form_datas['parcelsgeneral'] = [p] + p["parcel_number"] = "43" + self.form_datas[4].form_datas["parcelsgeneral"] = [p] self.operation_number = models.Operation.objects.count() self.parcel_number = models.Parcel.objects.count() def post_first_wizard(test_object, final_step_response): - test_object.assertEqual(models.Operation.objects.count(), - test_object.operation_number) - operation = models.Operation.objects.get( - pk=test_object.operations[0].pk) - test_object.assertEqual(operation.operation_type.pk, - self.ope_type.pk) + test_object.assertEqual( + models.Operation.objects.count(), test_object.operation_number + ) + operation = models.Operation.objects.get(pk=test_object.operations[0].pk) + test_object.assertEqual(operation.operation_type.pk, self.ope_type.pk) test_object.assertEqual(operation.year, 2017) - test_object.assertEqual(models.Parcel.objects.count(), - test_object.parcel_number + 1) - test_object.assertEqual(operation.parcels.count(), - test_object.parcel_number + 1) + test_object.assertEqual( + models.Parcel.objects.count(), test_object.parcel_number + 1 + ) + test_object.assertEqual( + operation.parcels.count(), test_object.parcel_number + 1 + ) def pre_second_wizard(test_object): test_object.form_datas[1].form_datas[ - 'parcelsgeneral-operation_modification'][0]["pk"] = \ - models.Parcel.objects.get(parcel_number="42").pk + "parcelsgeneral-operation_modification" + ][0]["pk"] = models.Parcel.objects.get(parcel_number="42").pk def post_second_wizard(test_object, final_step_response): - test_object.assertEqual(models.Operation.objects.count(), - test_object.operation_number) - operation = models.Operation.objects.get( - pk=test_object.operations[0].pk) - test_object.assertEqual(operation.operation_type.pk, - self.ope_type.pk) + test_object.assertEqual( + models.Operation.objects.count(), test_object.operation_number + ) + operation = models.Operation.objects.get(pk=test_object.operations[0].pk) + test_object.assertEqual(operation.operation_type.pk, self.ope_type.pk) test_object.assertEqual(operation.year, 2017) - test_object.assertEqual(models.Parcel.objects.count(), - test_object.parcel_number + 1) + test_object.assertEqual( + models.Parcel.objects.count(), test_object.parcel_number + 1 + ) # the init parcel is not submited but have a context record # the init parcel is not detached from the operation - test_object.assertEqual(operation.parcels.count(), - test_object.parcel_number + 1) + test_object.assertEqual( + operation.parcels.count(), test_object.parcel_number + 1 + ) # update the external id on update cr = ContextRecord.objects.get(pk=self.cr.pk) - test_object.assertEqual(cr.external_id, - "codeope42-12345-A1-Context record") + test_object.assertEqual(cr.external_id, "codeope42-12345-A1-Context record") def pre_third_wizard(test_object): parcel_nb = models.Parcel.objects.count() test_object.cr.delete() - test_object.assertEqual( - parcel_nb, models.Parcel.objects.count()) + test_object.assertEqual(parcel_nb, models.Parcel.objects.count()) def post_third_wizard(test_object, final_step_response): - test_object.assertEqual(models.Operation.objects.count(), - test_object.operation_number) - operation = models.Operation.objects.get( - pk=test_object.operations[0].pk) - test_object.assertEqual(operation.operation_type.pk, - self.ope_type.pk) + test_object.assertEqual( + models.Operation.objects.count(), test_object.operation_number + ) + operation = models.Operation.objects.get(pk=test_object.operations[0].pk) + test_object.assertEqual(operation.operation_type.pk, self.ope_type.pk) test_object.assertEqual(operation.year, 2017) # with no attach the parcel is deleted - test_object.assertEqual(operation.parcels.count(), - test_object.parcel_number) + test_object.assertEqual( + operation.parcels.count(), test_object.parcel_number + ) # the parcel object is no more automatically deleted - test_object.assertEqual(models.Parcel.objects.count(), - test_object.parcel_number + 1) + test_object.assertEqual( + models.Parcel.objects.count(), test_object.parcel_number + 1 + ) def pre_fifth_wizard(test_object): test_object.parcel_number = models.Parcel.objects.count() - operation = models.Operation.objects.get( - pk=test_object.operations[0].pk) + operation = models.Operation.objects.get(pk=test_object.operations[0].pk) test_object.operation_parcel_number = operation.parcels.count() test_object.form_datas[4].form_datas[ - 'parcelsgeneral-operation_modification'][0]["pk"] = \ - models.Parcel.objects.get(parcel_number="42").pk + "parcelsgeneral-operation_modification" + ][0]["pk"] = models.Parcel.objects.get(parcel_number="42").pk def post_fifth_wizard(test_object, final_step_response): - test_object.assertEqual(models.Operation.objects.count(), - test_object.operation_number) - operation = models.Operation.objects.get( - pk=test_object.operations[0].pk) - test_object.assertEqual(models.Parcel.objects.count(), - test_object.parcel_number) - test_object.assertEqual(operation.parcels.count(), - test_object.operation_parcel_number) + test_object.assertEqual( + models.Operation.objects.count(), test_object.operation_number + ) + operation = models.Operation.objects.get(pk=test_object.operations[0].pk) + test_object.assertEqual( + models.Parcel.objects.count(), test_object.parcel_number + ) + test_object.assertEqual( + operation.parcels.count(), test_object.operation_parcel_number + ) self.form_datas[0].extra_tests = [post_first_wizard] self.form_datas[1].pre_tests = [pre_second_wizard] @@ -3046,16 +3543,16 @@ class OperationWizardModifTest(WizardTest, OperationInitTest, TestCase): class OperationWizardDeleteTest(OperationWizardCreationTest): fixtures = FILE_FIXTURES - url_name = 'operation_deletion' - wizard_name = 'operation_deletion_wizard' + url_name = "operation_deletion" + wizard_name = "operation_deletion_wizard" steps = views.operation_deletion_steps redirect_url = "/{}/selec-{}".format(url_name, url_name) form_datas = [ FormData( "Wizard deletion test", form_datas={ - 'selec-operation_deletion': {'pks': None}, - } + "selec-operation_deletion": {"pks": None}, + }, ) ] @@ -3068,38 +3565,35 @@ class OperationWizardDeleteTest(OperationWizardCreationTest): self.ope = self.get_default_operation(force=True) self.ope.parcels.add(self.create_parcel()[0]) self.parcel_nb = models.Parcel.objects.count() - self.form_datas[0].form_datas['selec-operation_deletion']['pks'] = \ - self.ope.pk + self.form_datas[0].form_datas["selec-operation_deletion"]["pks"] = self.ope.pk self.operation_number = models.Operation.objects.count() super(OperationWizardDeleteTest, self).pre_wizard() def post_wizard(self): - self.assertEqual(self.operation_number - 1, - models.Operation.objects.count()) + self.assertEqual(self.operation_number - 1, models.Operation.objects.count()) # associated parcel is... no more removed self.assertEqual(self.parcel_nb, models.Parcel.objects.count()) class OperationWizardClosingTest(OperationWizardCreationTest): fixtures = FILE_FIXTURES - url_name = 'operation_closing' - wizard_name = 'operation_closing_wizard' + url_name = "operation_closing" + wizard_name = "operation_closing_wizard" steps = views.operation_closing_steps redirect_url = "/operation_closing/done" form_datas = [ FormData( "Wizard closing test", form_datas={ - 'selec-operation_closing': {'pk': None}, - 'date-operation_closing': {'end_date': '2016-01-01'}, - } + "selec-operation_closing": {"pk": None}, + "date-operation_closing": {"end_date": "2016-01-01"}, + }, ) ] def pre_wizard(self): self.ope = self.get_default_operation() - self.form_datas[0].form_datas['selec-operation_closing']['pk'] = \ - self.ope.pk + self.form_datas[0].form_datas["selec-operation_closing"]["pk"] = self.ope.pk self.assertTrue(self.ope.is_active()) super(OperationWizardClosingTest, self).pre_wizard() @@ -3107,25 +3601,24 @@ class OperationWizardClosingTest(OperationWizardCreationTest): ope = models.Operation.objects.get(pk=self.ope.pk) self.assertFalse(ope.is_active()) self.assertEqual( - ope.closing()['date'].strftime('%Y-%d-%m'), - self.form_datas[0].form_datas['date-operation_closing']['end_date'] + ope.closing()["date"].strftime("%Y-%d-%m"), + self.form_datas[0].form_datas["date-operation_closing"]["end_date"], ) -class OperationAdminActWizardCreationTest(WizardTest, OperationInitTest, - TestCase): +class OperationAdminActWizardCreationTest(WizardTest, OperationInitTest, TestCase): fixtures = FILE_FIXTURES - url_name = 'operation_administrativeactop' - wizard_name = 'operation_administrative_act_wizard' + url_name = "operation_administrativeactop" + wizard_name = "operation_administrative_act_wizard" steps = views.administrativeactop_steps form_datas = [ FormData( "Admin act creation", form_datas={ - 'selec-operation_administrativeactop': {}, - 'administrativeact-operation_administrativeactop': { - 'signature_date': str(datetime.date.today()) - } + "selec-operation_administrativeactop": {}, + "administrativeact-operation_administrativeactop": { + "signature_date": str(datetime.date.today()) + }, }, ) ] @@ -3135,38 +3628,34 @@ class OperationAdminActWizardCreationTest(WizardTest, OperationInitTest, self.number = models.AdministrativeAct.objects.count() data = self.form_datas[0].form_datas - data['selec-operation_administrativeactop']['pk'] = ope.pk - act = models.ActType.objects.filter(intented_to='O').all()[0].pk + data["selec-operation_administrativeactop"]["pk"] = ope.pk + act = models.ActType.objects.filter(intented_to="O").all()[0].pk - data['administrativeact-operation_administrativeactop'][ - 'act_type'] = act + data["administrativeact-operation_administrativeactop"]["act_type"] = act super(OperationAdminActWizardCreationTest, self).pre_wizard() def post_wizard(self): - self.assertEqual(models.AdministrativeAct.objects.count(), - self.number + 1) + self.assertEqual(models.AdministrativeAct.objects.count(), self.number + 1) class SiteTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES def setUp(self): - IshtarSiteProfile.objects.get_or_create( - slug='default', active=True) + IshtarSiteProfile.objects.get_or_create(slug="default", active=True) self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='view_own_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="view_own_operation") + ) self.orgas = self.create_orgas(self.user) def test_create_or_update_top_operations(self): operation_0 = self.create_operation(self.user, self.orgas[0])[0] operation_1 = self.create_operation(self.alt_user, self.orgas[0])[1] - site = models.ArchaeologicalSite.objects.create( - reference="ref-site" - ) + site = models.ArchaeologicalSite.objects.create(reference="ref-site") site.create_or_update_top_operation() - q = models.ArchaeologicalSite.objects.filter(reference='ref-site') + q = models.ArchaeologicalSite.objects.filter(reference="ref-site") site = q.all()[0] # creation not forced - no creation self.assertEqual(site.top_operations.count(), 0) @@ -3188,8 +3677,7 @@ class SiteTest(TestCase, OperationInitTest): self.assertTrue(site.top_operation.virtual_operation) self.assertEqual(site.top_operation.right_relations.count(), 1) self.assertEqual( - site.top_operation.right_relations.all()[0].right_record, - operation_0 + site.top_operation.right_relations.all()[0].right_record, operation_0 ) # create with two operations attached @@ -3203,8 +3691,7 @@ class SiteTest(TestCase, OperationInitTest): self.assertTrue(site.top_operation.virtual_operation) self.assertEqual(site.top_operation.right_relations.count(), 2) attached = [ - rel.right_record - for rel in site.top_operation.right_relations.all() + rel.right_record for rel in site.top_operation.right_relations.all() ] self.assertIn(operation_0, attached) self.assertIn(operation_1, attached) @@ -3217,8 +3704,7 @@ class SiteTest(TestCase, OperationInitTest): self.assertTrue(site.top_operation.virtual_operation) self.assertEqual(site.top_operation.right_relations.count(), 1) self.assertEqual( - site.top_operation.right_relations.all()[0].right_record, - operation_0 + site.top_operation.right_relations.all()[0].right_record, operation_0 ) # reattach it @@ -3229,35 +3715,29 @@ class SiteTest(TestCase, OperationInitTest): self.assertTrue(site.top_operation.virtual_operation) self.assertEqual(site.top_operation.right_relations.count(), 2) attached = [ - rel.right_record - for rel in site.top_operation.right_relations.all() + rel.right_record for rel in site.top_operation.right_relations.all() ] self.assertIn(operation_0, attached) self.assertIn(operation_1, attached) def test_search(self): - site = models.ArchaeologicalSite.objects.create( - reference="reference-site" - ) + site = models.ArchaeologicalSite.objects.create(reference="reference-site") c = Client() - search = {'search_vector': 'reference="reference-site"'} - response = c.get(reverse('get-site'), search) + search = {"search_vector": 'reference="reference-site"'} + response = c.get(reverse("get-site"), search) # no result when no authentication self.assertTrue(not json.loads(response.content.decode())) c.login(username=self.username, password=self.password) - response = c.get(reverse('get-site'), search) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + response = c.get(reverse("get-site"), search) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) - search = {'search_vector': 'reference="reference"'} - response = c.get(reverse('get-site'), search) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 0) + search = {"search_vector": 'reference="reference"'} + response = c.get(reverse("get-site"), search) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 0) - search = {'search_vector': 'reference="reference*"'} - response = c.get(reverse('get-site'), search) - self.assertEqual(json.loads(response.content.decode())['recordsTotal'], - 1) + search = {"search_vector": 'reference="reference*"'} + response = c.get(reverse("get-site"), search) + self.assertEqual(json.loads(response.content.decode())["recordsTotal"], 1) class GenerateQRCode(OperationInitTest, TestCase): @@ -3274,14 +3754,15 @@ class GenerateQRCode(OperationInitTest, TestCase): operation = models.Operation.objects.get(pk=self.operation.pk) self.assertIn(operation.qrcode.name, ["", None]) c = Client() - url = reverse('qrcode-item', args=[ - 'archaeological-operations', 'operation', operation.pk]) + url = reverse( + "qrcode-item", args=["archaeological-operations", "operation", operation.pk] + ) response = c.get(url) self.assertEqual(response.status_code, 302) c.login(username=self.username, password=self.password) response = c.get(url) self.assertEqual(response.status_code, 200) - self.assertEqual(response['Content-Type'], "image/png") + self.assertEqual(response["Content-Type"], "image/png") operation = models.Operation.objects.get(pk=self.operation.pk) self.assertIsNotNone(operation.qrcode.name) @@ -3290,9 +3771,7 @@ class GenerateQRCode(OperationInitTest, TestCase): self.operation.generate_qrcode() self.assertIsNotNone(self.operation.qrcode.name) self.assertTrue( - self.operation.qrcode.name.startswith( - "operation/2010/OA1/qrcode" - ) + self.operation.qrcode.name.startswith("operation/2010/OA1/qrcode") ) @@ -3305,7 +3784,7 @@ class DocumentTest(OperationInitTest, TestCase): def test_create(self): c = Client() - url = reverse('create-document') + url = reverse("create-document") nb_doc = models.Document.objects.count() nb_doc_ope = self.operation.documents.count() @@ -3315,10 +3794,12 @@ class DocumentTest(OperationInitTest, TestCase): c.login(username=self.username, password=self.password) response = c.get(url, {"operation": self.operation.pk}) self.assertEqual(response.status_code, 200) - self.assertIn('option value="{}" selected'.format(self.operation.pk), - response.content.decode()) + self.assertIn( + 'option value="{}" selected'.format(self.operation.pk), + response.content.decode(), + ) - posted = {'authors': []} + posted = {"authors": []} for related_key in models.Document.RELATED_MODELS: posted[related_key] = [] posted["operations"] = [str(self.operation.pk)] @@ -3333,15 +3814,17 @@ class DocumentTest(OperationInitTest, TestCase): self.assertEqual(nb_doc + 1, models.Document.objects.count()) self.assertEqual(nb_doc_ope + 1, self.operation.documents.count()) self.assertRedirects( - response, '/document/edit/?open_item={}'.format( - self.operation.documents.order_by('-pk').all()[0].pk - )) + response, + "/document/edit/?open_item={}".format( + self.operation.documents.order_by("-pk").all()[0].pk + ), + ) def test_edit(self): doc = models.Document.objects.create(title="hop2") doc.operations.add(self.operation) c = Client() - url = reverse('edit-document', args=[doc.pk]) + url = reverse("edit-document", args=[doc.pk]) response = c.get(url) self.assertEqual(response.status_code, 302) @@ -3349,35 +3832,33 @@ class DocumentTest(OperationInitTest, TestCase): c.login(username=self.username, password=self.password) response = c.get(url) self.assertEqual(response.status_code, 200) - self.assertIn('option value="{}" selected'.format(self.operation.pk), - response.content.decode()) + self.assertIn( + 'option value="{}" selected'.format(self.operation.pk), + response.content.decode(), + ) - posted = { - 'authors': [], - 'title': "hop2-is-back" - } + posted = {"authors": [], "title": "hop2-is-back"} for related_key in models.Document.RELATED_MODELS: posted[related_key] = [] posted["operations"] = [str(self.operation.pk)] response = c.post(url, posted) - self.assertRedirects( - response, '/document/edit/?open_item={}'.format(doc.pk)) - response = c.get('/show-document/{}/'.format(doc.pk)) + self.assertRedirects(response, "/document/edit/?open_item={}".format(doc.pk)) + response = c.get("/show-document/{}/".format(doc.pk)) self.assertIn(posted["title"], response.content.decode()) class DocumentWizardDeleteTest(WizardTest, OperationInitTest, TestCase): fixtures = FILE_FIXTURES - url_name = 'document_deletion' + url_name = "document_deletion" url_uri = "document/delete" - wizard_name = 'document_deletion_wizard' + wizard_name = "document_deletion_wizard" redirect_url = "/{}/selec-{}".format(url_uri, url_name) steps = document_deletion_steps form_datas = [ FormData( "Delete document", form_datas={ - 'selec': {'pks': None}, + "selec": {"pks": None}, }, ), ] @@ -3387,41 +3868,44 @@ class DocumentWizardDeleteTest(WizardTest, OperationInitTest, TestCase): document = Document.objects.create(title="testy") document.operations.add(ope) self.ope_id = ope.pk - self.form_datas[0].set('selec', 'pks', document.pk) + self.form_datas[0].set("selec", "pks", document.pk) self.doc_nb = Document.objects.count() super(DocumentWizardDeleteTest, self).pre_wizard() def post_wizard(self): - self.assertEqual(Document.objects.count(), - self.doc_nb - 1) + self.assertEqual(Document.objects.count(), self.doc_nb - 1) # operation not deleted with the document - self.assertEqual(models.Operation.objects.filter( - pk=self.ope_id).count(), 1) + self.assertEqual(models.Operation.objects.filter(pk=self.ope_id).count(), 1) class AutocompleteTest(AutocompleteTestBase, TestCase): fixtures = OPERATION_FIXTURES models = [ - AcItem(models.Operation, 'autocomplete-operation', - prepare_func="create_operation"), - AcItem(models.ArchaeologicalSite, 'autocomplete-archaeologicalsite', - "reference"), - AcItem(models.Operation, 'autocomplete-patriarche', - prepare_func="create_operation_patriarche", - id_key="code_patriarche", one_word_search=True), + AcItem( + models.Operation, "autocomplete-operation", prepare_func="create_operation" + ), + AcItem( + models.ArchaeologicalSite, "autocomplete-archaeologicalsite", "reference" + ), + AcItem( + models.Operation, + "autocomplete-patriarche", + prepare_func="create_operation_patriarche", + id_key="code_patriarche", + one_word_search=True, + ), ] def create_operation(self, base_name): item, __ = models.Operation.objects.get_or_create( - common_name=base_name, - operation_type=models.OperationType.objects.all()[0] + common_name=base_name, operation_type=models.OperationType.objects.all()[0] ) return item, None def create_operation_patriarche(self, base_name): item, __ = models.Operation.objects.get_or_create( code_patriarche=base_name, - operation_type=models.OperationType.objects.all()[0] + operation_type=models.OperationType.objects.all()[0], ) return item, None @@ -3436,25 +3920,26 @@ class OperationQATest(OperationInitTest, TestCase): self.create_operation(self.user, self.orgas[0]) self.create_operation(self.user, self.orgas[0]) self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='change_operation')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="change_operation") + ) def test_lock(self): c = Client() op0, op1 = self.operations[0], self.operations[1] pks = "{}-{}".format(op0.pk, op1.pk) - url = reverse('operation-qa-lock', args=[pks]) + url = reverse("operation-qa-lock", args=[pks]) response = c.get(url) self.assertEqual(response.status_code, 404) c.login(username=self.username, password=self.password) - response = c.get(reverse('operation-qa-lock', args=[pks])) + response = c.get(reverse("operation-qa-lock", args=[pks])) self.assertEqual(response.status_code, 200) response = c.post(url, {"action": "lock"}) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") for ope in (op0, op1): ope = models.Operation.objects.get(pk=ope.pk) self.assertEqual(ope.locked, True) @@ -3462,7 +3947,7 @@ class OperationQATest(OperationInitTest, TestCase): response = c.post(url, {"action": "unlock"}) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") for ope in (op0, op1): ope = models.Operation.objects.get(pk=ope.pk) self.assertEqual(ope.locked, False) @@ -3470,12 +3955,12 @@ class OperationQATest(OperationInitTest, TestCase): c = Client() c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('operation-qa-lock', args=[pks])) + response = c.get(reverse("operation-qa-lock", args=[pks])) self.assertEqual(response.status_code, 200) response = c.post(url, {"action": "lock"}) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") for ope in (op0, op1): ope = models.Operation.objects.get(pk=ope.pk) self.assertEqual(ope.locked, True) @@ -3483,7 +3968,7 @@ class OperationQATest(OperationInitTest, TestCase): response = c.post(url, {"action": "unlock"}) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") for ope in (op0, op1): ope = models.Operation.objects.get(pk=ope.pk) self.assertEqual(ope.locked, False) @@ -3500,7 +3985,7 @@ class OperationQATest(OperationInitTest, TestCase): op1.save() response = c.post(url, {"action": "unlock"}) - self.assertRedirects(response, '/qa-not-available/locked-by-others/') + self.assertRedirects(response, "/qa-not-available/locked-by-others/") op0 = models.Operation.objects.get(pk=op0.pk) self.assertEqual(op0.locked, True) @@ -3513,17 +3998,17 @@ class OperationQATest(OperationInitTest, TestCase): def test_bulk_update(self): c = Client() pks = "{}-{}".format(self.operations[0].pk, self.operations[1].pk) - response = c.get(reverse('operation-qa-bulk-update', args=[pks])) - self.assertRedirects(response, '/') + response = c.get(reverse("operation-qa-bulk-update", args=[pks])) + self.assertRedirects(response, "/") c = Client() c.login(username=self.username, password=self.password) - response = c.get(reverse('operation-qa-bulk-update', args=[pks])) + response = c.get(reverse("operation-qa-bulk-update", args=[pks])) self.assertEqual(response.status_code, 200) c = Client() c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('operation-qa-bulk-update', args=[pks])) + response = c.get(reverse("operation-qa-bulk-update", args=[pks])) self.assertEqual(response.status_code, 200) operation_0 = self.operations[0] @@ -3536,30 +4021,31 @@ class OperationQATest(OperationInitTest, TestCase): operation_1.save() operation_type = models.OperationType.objects.exclude( - txt_idx="arch_diagnostic").all()[0] + txt_idx="arch_diagnostic" + ).all()[0] self.assertNotEqual( models.Operation.objects.get(pk=operation_0.pk).operation_type, - operation_type + operation_type, ) self.assertNotEqual( models.Operation.objects.get(pk=operation_1.pk).operation_type, - operation_type + operation_type, ) response = c.post( - reverse('operation-qa-bulk-update-confirm', args=[pks]), - {'qa_operation_type': operation_type.pk} + reverse("operation-qa-bulk-update-confirm", args=[pks]), + {"qa_operation_type": operation_type.pk}, ) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") self.assertEqual( models.Operation.objects.get(pk=operation_0.pk).operation_type, - operation_type + operation_type, ) self.assertEqual( models.Operation.objects.get(pk=operation_1.pk).operation_type, - operation_type + operation_type, ) # one item lock by another user @@ -3569,10 +4055,10 @@ class OperationQATest(OperationInitTest, TestCase): op0.save() response = c.post( - reverse('operation-qa-bulk-update-confirm', args=[pks]), - {'qa_operation_type': operation_type.pk} + reverse("operation-qa-bulk-update-confirm", args=[pks]), + {"qa_operation_type": operation_type.pk}, ) - self.assertRedirects(response, '/qa-not-available/locked/') + self.assertRedirects(response, "/qa-not-available/locked/") class DocumentQATest(OperationInitTest, TestCase): @@ -3582,58 +4068,54 @@ class DocumentQATest(OperationInitTest, TestCase): def setUp(self): self.username, self.password, self.user = create_superuser() self.alt_username, self.alt_password, self.alt_user = create_user() - self.alt_user.user_permissions.add(Permission.objects.get( - codename='change_document')) + self.alt_user.user_permissions.add( + Permission.objects.get(codename="change_document") + ) self.source_1 = models.Document.objects.create( - title="Source title", - source_type=models.SourceType.objects.all()[0] + title="Source title", source_type=models.SourceType.objects.all()[0] ) self.source_2 = models.Document.objects.create( - title="Source title2", - source_type=models.SourceType.objects.all()[0] + title="Source title2", source_type=models.SourceType.objects.all()[0] ) def test_bulk_update(self): c = Client() pks = "{}-{}".format(self.source_1.pk, self.source_2.pk) - response = c.get(reverse('document-qa-bulk-update', args=[pks])) - self.assertRedirects(response, '/') + response = c.get(reverse("document-qa-bulk-update", args=[pks])) + self.assertRedirects(response, "/") c = Client() c.login(username=self.username, password=self.password) - response = c.get(reverse('document-qa-bulk-update', args=[pks])) + response = c.get(reverse("document-qa-bulk-update", args=[pks])) self.assertEqual(response.status_code, 200) c = Client() c.login(username=self.alt_username, password=self.alt_password) - response = c.get(reverse('document-qa-bulk-update', args=[pks])) + response = c.get(reverse("document-qa-bulk-update", args=[pks])) self.assertEqual(response.status_code, 200) document_0 = self.source_1 document_1 = self.source_2 source_type = models.SourceType.objects.exclude( - txt_idx=self.source_1.source_type.txt_idx).all()[0] + txt_idx=self.source_1.source_type.txt_idx + ).all()[0] self.assertNotEqual( - models.Document.objects.get(pk=document_0.pk).source_type, - source_type + models.Document.objects.get(pk=document_0.pk).source_type, source_type ) self.assertNotEqual( - models.Document.objects.get(pk=document_1.pk).source_type, - source_type + models.Document.objects.get(pk=document_1.pk).source_type, source_type ) response = c.post( - reverse('document-qa-bulk-update-confirm', args=[pks]), - {'qa_source_type': source_type.pk} + reverse("document-qa-bulk-update-confirm", args=[pks]), + {"qa_source_type": source_type.pk}, ) if response.status_code != 200: - self.assertRedirects(response, '/success/') + self.assertRedirects(response, "/success/") self.assertEqual( - models.Document.objects.get(pk=document_0.pk).source_type, - source_type + models.Document.objects.get(pk=document_0.pk).source_type, source_type ) self.assertEqual( - models.Document.objects.get(pk=document_1.pk).source_type, - source_type + models.Document.objects.get(pk=document_1.pk).source_type, source_type ) diff --git a/archaeological_operations/urls.py b/archaeological_operations/urls.py index 6961af39a..85a650216 100644 --- a/archaeological_operations/urls.py +++ b/archaeological_operations/urls.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -27,196 +27,333 @@ from archaeological_operations import models # forms urlpatterns = [ - url(r'operation_administrativeactop_search/(?P<step>.+)?$', - check_rights(['change_administrativeact'])( - views.operation_administrativeactop_search_wizard), - name='operation_administrativeactop_search'), - url(r'operation_administrativeactop/(?P<step>.+)?$', - check_rights(['change_administrativeact'])( - views.operation_administrativeactop_wizard), - name='operation_administrativeactop'), - url(r'operation_administrativeactop_modification/(?P<step>.+)?$', - check_rights(['change_administrativeact'])( - views.operation_administrativeactop_modification_wizard), - name='operation_administrativeactop_modification'), - url(r'operation_administrativeactop_modify/(?P<pk>.+)/$', + url( + r"operation_administrativeactop_search/(?P<step>.+)?$", + check_rights(["change_administrativeact"])( + views.operation_administrativeactop_search_wizard + ), + name="operation_administrativeactop_search", + ), + url( + r"operation_administrativeactop/(?P<step>.+)?$", + check_rights(["change_administrativeact"])( + views.operation_administrativeactop_wizard + ), + name="operation_administrativeactop", + ), + url( + r"operation_administrativeactop_modification/(?P<step>.+)?$", + check_rights(["change_administrativeact"])( + views.operation_administrativeactop_modification_wizard + ), + name="operation_administrativeactop_modification", + ), + url( + r"operation_administrativeactop_modify/(?P<pk>.+)/$", views.operation_administrativeactop_modify, - name='operation_administrativeactop_modify'), - url(r'operation_administrativeactop_deletion/(?P<step>.+)?$', - check_rights(['change_administrativeact'])( - views.operation_administrativeactop_deletion_wizard), - name='operation_administrativeactop_deletion'), - url(r'operation_administrativeactop_delete/(?P<pk>.+)/$', + name="operation_administrativeactop_modify", + ), + url( + r"operation_administrativeactop_deletion/(?P<step>.+)?$", + check_rights(["change_administrativeact"])( + views.operation_administrativeactop_deletion_wizard + ), + name="operation_administrativeactop_deletion", + ), + url( + r"operation_administrativeactop_delete/(?P<pk>.+)/$", views.operation_administrativeactop_delete, - name='delete-administrativeact-operation'), - - url(r'operation_search/(?P<step>.+)?$', - check_rights(['view_operation', 'view_own_operation'])( - views.operation_search_wizard), name='operation_search'), - url(r'operation_creation/(?P<step>.+)?$', - check_rights(['add_operation', 'add_own_operation'])( - views.operation_creation_wizard), - name='operation_creation'), - url(r'operation_add/(?P<file_id>\d+)$', - views.operation_add, name='operation_add'), - url(r'operation_modification/(?P<step>.+)?$', - check_rights(['change_operation', 'change_own_operation'])( - views.operation_modification_wizard), - name='operation_modification'), - url(r'operation_modify/(?P<pk>.+)/$', - views.operation_modify, name='operation_modify'), - url(r'operation_closing/(?P<step>.+)?$', - check_rights(['change_operation'])( - views.operation_closing_wizard), name='operation_closing'), - url(r'operation_deletion/(?P<step>.+)?$', - check_rights(['change_operation', 'change_own_operation'])( - views.operation_deletion_wizard), name='operation_deletion'), - url(r'operation_delete/(?P<pk>.+)/$', - views.operation_delete, name='delete-operation'), - - url(r'administrativact_register/(?P<step>.+)?$', - check_rights(['view_administrativeact', 'view_own_administrativeact'])( - views.administrativact_register_wizard), - name='administrativact_register'), - - url(r'autocomplete-operation/$', views.autocomplete_operation, - name='autocomplete-operation'), - url(r'get-operation/own/(?P<type>.+)?$', - views.get_operation, name='get-own-operation', - kwargs={'force_own': True}), - url(r'get-operation/(?P<type>.+)?$', views.get_operation, - name='get-operation'), - url(r'get-operation-full/own/(?P<type>.+)?$', - views.get_operation, name='get-own-operation-full', - kwargs={'full': True, 'force_own': True}), - url(r'get-operation-full/(?P<type>.+)?$', views.get_operation, - name='get-operation-full', kwargs={'full': True}), - url(r'get-operation-shortcut/(?P<type>.+)?$', - views.get_operation, name='get-operation-shortcut', - kwargs={'full': 'shortcut'}), - url(r'get-available-operation-code/(?P<year>.+)?$', + name="delete-administrativeact-operation", + ), + url( + r"operation_search/(?P<step>.+)?$", + check_rights(["view_operation", "view_own_operation"])( + views.operation_search_wizard + ), + name="operation_search", + ), + url( + r"operation_creation/(?P<step>.+)?$", + check_rights(["add_operation", "add_own_operation"])( + views.operation_creation_wizard + ), + name="operation_creation", + ), + url(r"operation_add/(?P<file_id>\d+)$", views.operation_add, name="operation_add"), + url( + r"operation_modification/(?P<step>.+)?$", + check_rights(["change_operation", "change_own_operation"])( + views.operation_modification_wizard + ), + name="operation_modification", + ), + url( + r"operation_modify/(?P<pk>.+)/$", + views.operation_modify, + name="operation_modify", + ), + url( + r"operation_closing/(?P<step>.+)?$", + check_rights(["change_operation"])(views.operation_closing_wizard), + name="operation_closing", + ), + url( + r"operation_deletion/(?P<step>.+)?$", + check_rights(["change_operation", "change_own_operation"])( + views.operation_deletion_wizard + ), + name="operation_deletion", + ), + url( + r"operation_delete/(?P<pk>.+)/$", + views.operation_delete, + name="delete-operation", + ), + url( + r"administrativact_register/(?P<step>.+)?$", + check_rights(["view_administrativeact", "view_own_administrativeact"])( + views.administrativact_register_wizard + ), + name="administrativact_register", + ), + url( + r"autocomplete-operation/$", + views.autocomplete_operation, + name="autocomplete-operation", + ), + url( + r"get-operation/own/(?P<type>.+)?$", + views.get_operation, + name="get-own-operation", + kwargs={"force_own": True}, + ), + url(r"get-operation/(?P<type>.+)?$", views.get_operation, name="get-operation"), + url( + r"get-operation-full/own/(?P<type>.+)?$", + views.get_operation, + name="get-own-operation-full", + kwargs={"full": True, "force_own": True}, + ), + url( + r"get-operation-full/(?P<type>.+)?$", + views.get_operation, + name="get-operation-full", + kwargs={"full": True}, + ), + url( + r"get-operation-shortcut/(?P<type>.+)?$", + views.get_operation, + name="get-operation-shortcut", + kwargs={"full": "shortcut"}, + ), + url( + r"get-available-operation-code/(?P<year>.+)?$", views.get_available_operation_code, - name='get_available_operation_code'), - url(r'revert-operation/(?P<pk>.+)/(?P<date>.+)$', - views.revert_operation, name='revert-operation'), - url(r'show-operation(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_operation, name=models.Operation.SHOW_URL), - url(r'show-historized-operation/(?P<pk>.+)?/(?P<date>.+)?$', - views.show_operation, name='show-historized-operation'), - url(r'get-administrativeactop/(?P<type>.+)?$', - views.get_administrativeactop, name='get-administrativeactop'), - url(r'get-administrativeact/(?P<type>.+)?$', - views.get_administrativeact, name='get-administrativeact'), - url(r'get-administrativeact-full/(?P<type>.+)?$', - views.get_administrativeact, name='get-administrativeact-full', - kwargs={'full': True}), - url(r'show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_administrativeact, name='show-administrativeact'), + name="get_available_operation_code", + ), + url( + r"revert-operation/(?P<pk>.+)/(?P<date>.+)$", + views.revert_operation, + name="revert-operation", + ), + url( + r"show-operation(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_operation, + name=models.Operation.SHOW_URL, + ), + url( + r"show-historized-operation/(?P<pk>.+)?/(?P<date>.+)?$", + views.show_operation, + name="show-historized-operation", + ), + url( + r"get-administrativeactop/(?P<type>.+)?$", + views.get_administrativeactop, + name="get-administrativeactop", + ), + url( + r"get-administrativeact/(?P<type>.+)?$", + views.get_administrativeact, + name="get-administrativeact", + ), + url( + r"get-administrativeact-full/(?P<type>.+)?$", + views.get_administrativeact, + name="get-administrativeact-full", + kwargs={"full": True}, + ), + url( + r"show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_administrativeact, + name="show-administrativeact", + ), # allow specialization for operations - url(r'show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_administrativeact, name='show-administrativeactop'), + url( + r"show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_administrativeact, + name="show-administrativeactop", + ), # allow specialization for files, treatment, treatment request - url(r'show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_administrativeact, name='show-administrativeactfile'), - url(r'show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_administrativeact, name='show-administrativeacttreatment'), - url(r'show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$', + url( + r"show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_administrativeact, + name="show-administrativeactfile", + ), + url( + r"show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_administrativeact, + name="show-administrativeacttreatment", + ), + url( + r"show-administrativeact(?:/(?P<pk>.+))?/(?P<type>.+)?$", views.show_administrativeact, - name='show-administrativeacttreatmentfile'), - url(r'generatedoc-administrativeactop/(?P<pk>.+)?/(?P<template_pk>.+)?$', + name="show-administrativeacttreatmentfile", + ), + url( + r"generatedoc-administrativeactop/(?P<pk>.+)?/(?P<template_pk>.+)?$", views.generatedoc_administrativeactop, - name='generatedoc-administrativeactop'), - url(r'dashboard_operation/$', views.dashboard_operation, - name='dashboard-operation'), - url(r'autocomplete-administrativeact/$', + name="generatedoc-administrativeactop", + ), + url( + r"dashboard_operation/$", views.dashboard_operation, name="dashboard-operation" + ), + url( + r"autocomplete-administrativeact/$", views.autocomplete_administrativeact, - name='autocomplete-administrativeact'), - - url(r'autocomplete-archaeologicalsite/$', + name="autocomplete-administrativeact", + ), + url( + r"autocomplete-archaeologicalsite/$", views.autocomplete_archaeologicalsite, - name='autocomplete-archaeologicalsite'), - url(r'new-archaeologicalsite/(?:(?P<parent_name>[^/]+)/)?' - r'(?:(?P<limits>[^/]+)/)?$', - views.new_archaeologicalsite, name='new-archaeologicalsite'), - url(r'get-site/(?P<type>.+)?$', - views.get_site, name='get-site'), - url(r'get-site-full/(?P<type>.+)?$', - views.get_site, name='get-site-full', kwargs={'full': True}), - url(r'get-site-shortcut/(?P<type>.+)?$', - views.get_site, name='get-site-shortcut', - kwargs={'full': 'shortcut'}), - url(r'revert-site/(?P<pk>.+)/(?P<date>.+)$', - views.revert_site, name='revert-site'), - url(r'show-site(?:/(?P<pk>.+))?/(?P<type>.+)?$', - views.show_site, name=models.ArchaeologicalSite.SHOW_URL), - url(r'show-historized-site/(?P<pk>.+)?/(?P<date>.+)?$', - views.show_site, name='show-historized-site'), - url(r'site_search/(?P<step>.+)?$', - check_rights(['view_archaeologicalsite', - 'view_own_archaeologicalsite'])( - views.site_search_wizard), name='site_search'), - url(r'site_creation/(?P<step>.+)?$', - check_rights(['add_archaeologicalsite', - 'add_own_archaeologicalsite'])( - views.site_creation_wizard), - name='site_creation'), - url(r'site_modification/(?P<step>.+)?$', - check_rights(['change_archaeologicalsite', - 'change_own_archaeologicalsite'])( - views.site_modification_wizard), - name='site_modification'), - url(r'site_modify/(?P<pk>.+)/$', - views.site_modify, name='site_modify'), - url(r'site_deletion/(?P<step>.+)?$', - check_rights(['change_archaeologicalsite'])( - views.site_deletion_wizard), - name='site_deletion'), - url(r'site_delete/(?P<pk>.+)/$', - views.site_delete, name='delete-site'), - - url(r'autocomplete-patriarche/$', views.autocomplete_patriarche, - name='autocomplete-patriarche'), - url(r'operation_administrativeact_document/$', + name="autocomplete-archaeologicalsite", + ), + url( + r"new-archaeologicalsite/(?:(?P<parent_name>[^/]+)/)?" + r"(?:(?P<limits>[^/]+)/)?$", + views.new_archaeologicalsite, + name="new-archaeologicalsite", + ), + url(r"get-site/(?P<type>.+)?$", views.get_site, name="get-site"), + url( + r"get-site-full/(?P<type>.+)?$", + views.get_site, + name="get-site-full", + kwargs={"full": True}, + ), + url( + r"get-site-shortcut/(?P<type>.+)?$", + views.get_site, + name="get-site-shortcut", + kwargs={"full": "shortcut"}, + ), + url(r"revert-site/(?P<pk>.+)/(?P<date>.+)$", views.revert_site, name="revert-site"), + url( + r"show-site(?:/(?P<pk>.+))?/(?P<type>.+)?$", + views.show_site, + name=models.ArchaeologicalSite.SHOW_URL, + ), + url( + r"show-historized-site/(?P<pk>.+)?/(?P<date>.+)?$", + views.show_site, + name="show-historized-site", + ), + url( + r"site_search/(?P<step>.+)?$", + check_rights(["view_archaeologicalsite", "view_own_archaeologicalsite"])( + views.site_search_wizard + ), + name="site_search", + ), + url( + r"site_creation/(?P<step>.+)?$", + check_rights(["add_archaeologicalsite", "add_own_archaeologicalsite"])( + views.site_creation_wizard + ), + name="site_creation", + ), + url( + r"site_modification/(?P<step>.+)?$", + check_rights(["change_archaeologicalsite", "change_own_archaeologicalsite"])( + views.site_modification_wizard + ), + name="site_modification", + ), + url(r"site_modify/(?P<pk>.+)/$", views.site_modify, name="site_modify"), + url( + r"site_deletion/(?P<step>.+)?$", + check_rights(["change_archaeologicalsite"])(views.site_deletion_wizard), + name="site_deletion", + ), + url(r"site_delete/(?P<pk>.+)/$", views.site_delete, name="delete-site"), + url( + r"autocomplete-patriarche/$", + views.autocomplete_patriarche, + name="autocomplete-patriarche", + ), + url( + r"operation_administrativeact_document/$", views.administrativeactfile_document, - name='operation-administrativeact-document'), - - url(r'^operation-qa-bulk-update/(?P<pks>[0-9-]+)?/$', - check_rights(['change_operation', 'change_own_operation'])( - views.QAOperationForm.as_view()), - name='operation-qa-bulk-update'), - url(r'^operation-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$', - check_rights(['change_operation', 'change_own_operation'])( - views.QAOperationForm.as_view()), - name='operation-qa-bulk-update-confirm', kwargs={"confirm": True}), - url(r'^operation-qa-duplicate/(?P<pks>[0-9-]+)?/$', - check_rights(['change_operation', 'change_own_operation'])( - views.QAOperationdDuplicateFormView.as_view()), - name='operation-qa-duplicate'), - - url(r'^operation-qa-lock/(?P<pks>[0-9-]+)?/$', - views.QAOperationLockView.as_view(), name='operation-qa-lock', - kwargs={"model": models.Operation}), - - url(r'^site-qa-duplicate/(?P<pks>[0-9-]+)?/$', - check_rights(['change_archaeologicalsite', - 'change_own_archaeologicalsite'])( - views.QAArchaeologicalSiteDuplicateFormView.as_view()), - name='site-qa-duplicate'), - url(r'^site-qa-lock/(?P<pks>[0-9-]+)?/$', - views.QASiteLockView.as_view(), name='site-qa-lock', - kwargs={"model": models.ArchaeologicalSite}), - url(r'^site-qa-bulk-update/(?P<pks>[0-9-]+)?/$', - check_rights(['change_archaeologicalsite', - 'change_own_archaeologicalsite'])( - views.QAArchaeologicalSiteForm.as_view()), - name='site-qa-bulk-update'), - url(r'^site-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$', - check_rights(['change_archaeologicalsite', - 'change_own_archaeologicalsite'])( - views.QAArchaeologicalSiteForm.as_view()), - name='site-qa-bulk-update-confirm', kwargs={"confirm": True}), - - url(r'generate-stats-operation/(?P<pk>.+)/', + name="operation-administrativeact-document", + ), + url( + r"^operation-qa-bulk-update/(?P<pks>[0-9-]+)?/$", + check_rights(["change_operation", "change_own_operation"])( + views.QAOperationForm.as_view() + ), + name="operation-qa-bulk-update", + ), + url( + r"^operation-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", + check_rights(["change_operation", "change_own_operation"])( + views.QAOperationForm.as_view() + ), + name="operation-qa-bulk-update-confirm", + kwargs={"confirm": True}, + ), + url( + r"^operation-qa-duplicate/(?P<pks>[0-9-]+)?/$", + check_rights(["change_operation", "change_own_operation"])( + views.QAOperationdDuplicateFormView.as_view() + ), + name="operation-qa-duplicate", + ), + url( + r"^operation-qa-lock/(?P<pks>[0-9-]+)?/$", + views.QAOperationLockView.as_view(), + name="operation-qa-lock", + kwargs={"model": models.Operation}, + ), + url( + r"^site-qa-duplicate/(?P<pks>[0-9-]+)?/$", + check_rights(["change_archaeologicalsite", "change_own_archaeologicalsite"])( + views.QAArchaeologicalSiteDuplicateFormView.as_view() + ), + name="site-qa-duplicate", + ), + url( + r"^site-qa-lock/(?P<pks>[0-9-]+)?/$", + views.QASiteLockView.as_view(), + name="site-qa-lock", + kwargs={"model": models.ArchaeologicalSite}, + ), + url( + r"^site-qa-bulk-update/(?P<pks>[0-9-]+)?/$", + check_rights(["change_archaeologicalsite", "change_own_archaeologicalsite"])( + views.QAArchaeologicalSiteForm.as_view() + ), + name="site-qa-bulk-update", + ), + url( + r"^site-qa-bulk-update/(?P<pks>[0-9-]+)?/confirm/$", + check_rights(["change_archaeologicalsite", "change_own_archaeologicalsite"])( + views.QAArchaeologicalSiteForm.as_view() + ), + name="site-qa-bulk-update-confirm", + kwargs={"confirm": True}, + ), + url( + r"generate-stats-operation/(?P<pk>.+)/", views.GenerateStatsOperation.as_view(), - name='generate-stats-operation'), + name="generate-stats-operation", + ), ] diff --git a/archaeological_operations/utils.py b/archaeological_operations/utils.py index bf38a675a..ba4f17358 100644 --- a/archaeological_operations/utils.py +++ b/archaeological_operations/utils.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -28,35 +28,43 @@ from django.core.exceptions import ObjectDoesNotExist from django.template.defaultfilters import slugify from django.contrib.auth.models import User -from ishtar_common.models import Town, Person, PersonType, OrganizationType, \ - Organization, SourceType +from ishtar_common.models import ( + Town, + Person, + PersonType, + OrganizationType, + Organization, + SourceType, +) from archaeological_files.models import PermitType -from archaeological_operations.models import OperationType, Period, \ - ActType +from archaeological_operations.models import OperationType, Period, ActType def get_default_person(): - return User.objects.order_by('pk').all()[0] + return User.objects.order_by("pk").all()[0] def _get_parse_string(trunc_number=None): def parse_string(value): value = value.strip() - if value == '#EMPTY': - value = '' - value = value.replace(' ', ' ') + if value == "#EMPTY": + value = "" + value = value.replace(" ", " ") if trunc_number: value = value[:trunc_number] return value + return parse_string + parse_string = _get_parse_string() def parse_multivalue(value): - s1 = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', value) - s1 = re.sub('([a-z0-9])([A-Z])', r'\1 \2', s1) - return re.sub('([0-9])([a-z])', r'\1 \2', s1) + s1 = re.sub("(.)([A-Z][a-z]+)", r"\1 \2", value) + s1 = re.sub("([a-z0-9])([A-Z])", r"\1 \2", s1) + return re.sub("([0-9])([a-z])", r"\1 \2", s1) + ope_types = {} @@ -65,8 +73,11 @@ def _init_ope_types(): for k in settings.ISHTAR_OPE_TYPES.keys(): ot, created = OperationType.objects.get_or_create( txt_idx=settings.ISHTAR_OPE_TYPES[k][0], - defaults={'label': settings.ISHTAR_OPE_TYPES[k][1], - 'preventive': k[0] == 'préventive'}) + defaults={ + "label": settings.ISHTAR_OPE_TYPES[k][1], + "preventive": k[0] == "préventive", + }, + ) ope_types[k] = ot @@ -78,6 +89,7 @@ def parse_operationtype(value, preventive, owner): return None return ope_types[value] + periods = {} periods_keys = [] @@ -102,25 +114,26 @@ def _init_period(): def parse_period(value): value = parse_string(value) - value = value[3:] if value.startswith('EUR') else value - while value.endswith('-'): + value = value[3:] if value.startswith("EUR") else value + while value.endswith("-"): value = value[:-1] - value = value[3:] if value.startswith('EUR') else value + value = value[3:] if value.startswith("EUR") else value if not periods: _init_period() if not value: - return [periods['']] - period, old_val = [], '' + return [periods[""]] + period, old_val = [], "" while value and old_val != value: old_val = value for k in periods_keys: if value.startswith(k): period.append(periods[k]) - value = value[len(k):] + value = value[len(k) :] break return period -_REPLACED_PERIOD = [('deuxieme', 'second')] + +_REPLACED_PERIOD = [("deuxieme", "second")] _REPLACED_PERIOD += [(y, x) for x, y in _REPLACED_PERIOD] REPLACED_PERIOD_DCT = dict(_REPLACED_PERIOD) @@ -133,18 +146,19 @@ def parse_period_name(value): _init_period() value = parse_string(value) if not value: - return [period_names['']] - period, old_val = [], '' + return [period_names[""]] + period, old_val = [], "" value = slugify(value) while value and old_val != value: old_val = value for k in period_names_keys: if value.startswith(k): period.append(period_names[k]) - value = value[len(k):] + value = value[len(k) :] break return period + _CACHED_PERMIT_TYPES = {} @@ -152,8 +166,8 @@ def _init_permit_type(): for k in settings.ISHTAR_PERMIT_TYPES: txt_idx, label = settings.ISHTAR_PERMIT_TYPES[k] permit_type, created = PermitType.objects.get_or_create( - txt_idx=txt_idx, defaults={'label': label, - 'available': True}) + txt_idx=txt_idx, defaults={"label": label, "available": True} + ) _CACHED_PERMIT_TYPES[k] = permit_type @@ -167,6 +181,7 @@ def parse_permittype(value): value = "" return _CACHED_PERMIT_TYPES[value] + _CACHED_ADMIN_ACT_TYPES = {} @@ -177,15 +192,16 @@ def parse_admin_act_typ(value, code, owner): return if code not in _CACHED_ADMIN_ACT_TYPES: act_type, created = ActType.objects.get_or_create( - txt_idx=code, defaults={'label': value}) + txt_idx=code, defaults={"label": value} + ) _CACHED_ADMIN_ACT_TYPES[code] = act_type return _CACHED_ADMIN_ACT_TYPES[code] def parse_fileref(value): - value = parse_string(value).split('/')[0] - value = value.split('.')[0] - match = re.search('[0-9].[0-9]*', value) + value = parse_string(value).split("/")[0] + value = value.split(".")[0] + match = re.search("[0-9].[0-9]*", value) if not match: return None return int(match.group()) @@ -203,18 +219,18 @@ def parse_orga(value, alternate_value, owner): try: organization_type = OrganizationType.objects.get(label__iexact=value) except ObjectDoesNotExist: - organization_type = OrganizationType.objects.get(txt_idx='undefined') - orga = Organization.objects.create(name=value, - organization_type=organization_type, - history_modifier=owner) + organization_type = OrganizationType.objects.get(txt_idx="undefined") + orga = Organization.objects.create( + name=value, organization_type=organization_type, history_modifier=owner + ) return orga def parse_bool(value): value = parse_string(value) - if value.lower() in ('yes', 'oui'): + if value.lower() in ("yes", "oui"): value = True - elif value.lower() in ('no', 'non'): + elif value.lower() in ("no", "non"): value = False else: value = None @@ -222,16 +238,16 @@ def parse_bool(value): def parse_date(value): - value = parse_string(value).split(' ')[0] + value = parse_string(value).split(" ")[0] try: - return datetime.datetime.strptime(value, '%d/%m/%Y') + return datetime.datetime.strptime(value, "%d/%m/%Y") except: return None def parse_yearref(value): - value = parse_string(value).split('.')[0] - match = re.search('[0-9].[0-9]*', value) + value = parse_string(value).split(".")[0] + match = re.search("[0-9].[0-9]*", value) if not match: return None return int(match.group()) @@ -239,7 +255,7 @@ def parse_yearref(value): def parse_surface(value): value = parse_string(value) - value = value.replace(',', '.') + value = value.replace(",", ".") try: # hectare en metre carrés value = float(value) * 10000 @@ -265,17 +281,17 @@ def parse_trunc_patriarche(value): value = parse_string(value) if not value: return - value = value.replace(' ', '') + value = value.replace(" ", "") try: int(value) except ValueError: return - return '18' + str(value) + return "18" + str(value) def parse_operation_code(value): value = parse_string(value) - code = value.split('.')[-1] + code = value.split(".")[-1] try: return int(code) except: @@ -291,44 +307,38 @@ def parse_title(value): def parse_name_surname(value, owner): value = parse_string(value) - items = value.split(' ') + items = value.split(" ") name = items[0] surname = "" if len(items) > 1: name = " ".join(items[:-1]) surname = items[-1] - values = {"surname": parse_title(surname)[:30], - "name": parse_title(name)[:30]} - if not values['surname'] and not values['name']: + values = {"surname": parse_title(surname)[:30], "name": parse_title(name)[:30]} + if not values["surname"] and not values["name"]: return q = Person.objects.filter(**values) if q.count(): return q.all()[0] else: - defaults = {'history_modifier': owner, - 'title': ''} + defaults = {"history_modifier": owner, "title": ""} defaults.update(values) p = Person.objects.create(**defaults) - p.person_types.add(PersonType.objects.get( - txt_idx='head_scientist')) + p.person_types.add(PersonType.objects.get(txt_idx="head_scientist")) return p def parse_person(surname, name, old_ref, owner): - values = {"surname": parse_title(surname), - "name": parse_title(name)} - if not values['surname'] and not values['name']: + values = {"surname": parse_title(surname), "name": parse_title(name)} + if not values["surname"] and not values["name"]: return q = Person.objects.filter(**values) if q.count(): return q.all()[0] else: - defaults = {'history_modifier': owner, - 'title': ''} + defaults = {"history_modifier": owner, "title": ""} defaults.update(values) p = Person.objects.create(**defaults) - p.person_types.add(PersonType.objects.get( - txt_idx='head_scientist')) + p.person_types.add(PersonType.objects.get(txt_idx="head_scientist")) return p @@ -344,48 +354,38 @@ def parse_comment_addr_nature(nature, addr, owner): return "" return "\n".join(comments) + # si pas de start date : premier janvier de year ope_types = { - 'AET': ('other_study', - 'Autre étude', True), - 'APP': ('assistance_preparation_help', - 'Aide à la préparation de publication', True), - 'DOC': ('documents_study', - 'Étude documentaire', True), - 'EV': ('evaluation', - "Fouille d'évaluation", True), - 'FOU': ('ancient_excavation', - "Fouille ancienne", True), - 'FP': ('prog_excavation', - "Fouille programmée", False), - 'MH': ('building_study', "Fouille avant MH", True), - 'OPD': ('arch_diagnostic', - "Diagnostic archéologique", True), - 'PAN': ('analysis_program', - "Programme d'analyses", False), - 'PCR': ('collective_research_project', - "Projet collectif de recherche", False), - 'PMS': ('specialized_eqp_prospection', - "Prospection avec matériel spécialisé", False), - 'PRD': ('diachronic_prospection', - "Prospection diachronique", False), - 'PI': ('diachronic_prospection', - "Prospection diachronique", False), - 'PRM': ('metal_detector_prospection', - "Prospection détecteur de métaux", False), - 'PRT': ('thematic_prospection', - "Prospection thématique", False), - 'PT': ('thematic_prospection', - "Prospection thématique", False), - 'RAR': ('cave_art_record', - "Relevé d'art rupestre", False), - 'SD': ('sampling_research', - "Sondage", False), - 'SP': ('prev_excavation', - "Fouille préventive", True), - 'SU': ('emergency_excavation', - "Fouille préventive d'urgence", True), + "AET": ("other_study", "Autre étude", True), + "APP": ( + "assistance_preparation_help", + "Aide à la préparation de publication", + True, + ), + "DOC": ("documents_study", "Étude documentaire", True), + "EV": ("evaluation", "Fouille d'évaluation", True), + "FOU": ("ancient_excavation", "Fouille ancienne", True), + "FP": ("prog_excavation", "Fouille programmée", False), + "MH": ("building_study", "Fouille avant MH", True), + "OPD": ("arch_diagnostic", "Diagnostic archéologique", True), + "PAN": ("analysis_program", "Programme d'analyses", False), + "PCR": ("collective_research_project", "Projet collectif de recherche", False), + "PMS": ( + "specialized_eqp_prospection", + "Prospection avec matériel spécialisé", + False, + ), + "PRD": ("diachronic_prospection", "Prospection diachronique", False), + "PI": ("diachronic_prospection", "Prospection diachronique", False), + "PRM": ("metal_detector_prospection", "Prospection détecteur de métaux", False), + "PRT": ("thematic_prospection", "Prospection thématique", False), + "PT": ("thematic_prospection", "Prospection thématique", False), + "RAR": ("cave_art_record", "Relevé d'art rupestre", False), + "SD": ("sampling_research", "Sondage", False), + "SP": ("prev_excavation", "Fouille préventive", True), + "SU": ("emergency_excavation", "Fouille préventive d'urgence", True), } _CACHED_OPE_TYPES = {} @@ -395,8 +395,8 @@ def _prepare_ope_types(): for k in ope_types.keys(): txt_idx, label, preventive = ope_types[k] ot, created = OperationType.objects.get_or_create( - txt_idx=txt_idx, defaults={'label': label, - 'preventive': preventive}) + txt_idx=txt_idx, defaults={"label": label, "preventive": preventive} + ) if k not in _CACHED_OPE_TYPES.keys(): _CACHED_OPE_TYPES[k] = ot @@ -406,16 +406,17 @@ def parse_patriarche_operationtype(value): return None return _CACHED_OPE_TYPES[value] -_dpt_re_filter = re.compile('^\([0-9]*\) ') + +_dpt_re_filter = re.compile("^\([0-9]*\) ") def parse_ope_name(value): if not value: - return '' + return "" value = value.strip() - if value.lower() == 'null': - return '' - value = _dpt_re_filter.sub('', value) + if value.lower() == "null": + return "" + value = _dpt_re_filter.sub("", value) return value @@ -430,10 +431,11 @@ def parse_ha(value): def parse_rapp_index(value): value = parse_string(value) - items = re.findall(r'[0-9]+$', value) + items = re.findall(r"[0-9]+$", value) if items: return int(items[-1]) + _CACHED_DOC_TYPES = {} @@ -443,8 +445,8 @@ def parse_doc_types(value): if value not in settings.ISHTAR_DOC_TYPES: return _CACHED_DOC_TYPES[value], created = SourceType.objects.get_or_create( - txt_idx=value, - defaults={"label": settings.ISHTAR_DOC_TYPES[value]}) + txt_idx=value, defaults={"label": settings.ISHTAR_DOC_TYPES[value]} + ) return _CACHED_DOC_TYPES[value] @@ -469,10 +471,10 @@ def parse_insee(value): PARCEL_YEAR_REGEXP = re.compile(r"^([0-9]{4})[ :]+") PARCEL_SECTION_REGEXP = re.compile( r"(?: )*(?:[Ss]ection(?:s)?)?(?: )*([A-Z][A-Z0-9]{0,3})[ :]*" - r"((?:(?: |;|,|[Pp]arcelle(?:s)?|n°|et|à|to)*[0-9]+[p]?)+)") -PARCEL_NB_RANGE_REGEXP = re.compile(r'([0-9]+[p]?) (?:à|to) ([0-9]+[p]?)') -PARCEL_NB_REGEXP = re.compile( - r'(?: |;|,|[Pp]arcelle(?:s)?|n°|et|à|to)*([0-9]+[p]?)') + r"((?:(?: |;|,|[Pp]arcelle(?:s)?|n°|et|à|to)*[0-9]+[p]?)+)" +) +PARCEL_NB_RANGE_REGEXP = re.compile(r"([0-9]+[p]?) (?:à|to) ([0-9]+[p]?)") +PARCEL_NB_REGEXP = re.compile(r"(?: |;|,|[Pp]arcelle(?:s)?|n°|et|à|to)*([0-9]+[p]?)") def parse_parcels(parcel_str, insee_code=None, owner=None): @@ -488,17 +490,17 @@ def parse_parcels(parcel_str, insee_code=None, owner=None): year = None if m: year = m.groups()[0] - parcel_str = parcel_str[m.span()[1]:] + parcel_str = parcel_str[m.span()[1] :] for parcel in PARCEL_SECTION_REGEXP.findall(parcel_str): sector, nums = parcel[0], parcel[1] for num in PARCEL_NB_REGEXP.findall(nums): if len(str(num)) > 6: continue - dct = {'year': year, 'section': sector, 'parcel_number': num} + dct = {"year": year, "section": sector, "parcel_number": num} if town: - dct['town'] = town + dct["town"] = town if owner: - dct['history_modifier'] = owner + dct["history_modifier"] = owner parcels.append(dct) for parcel_ranges in PARCEL_NB_RANGE_REGEXP.findall(nums): lower_range, higher_range = parcel_ranges @@ -509,11 +511,10 @@ def parse_parcels(parcel_str, insee_code=None, owner=None): except ValueError: continue for num in range(lower_range, higher_range): - dct = {'year': year, 'section': sector, - 'parcel_number': str(num)} + dct = {"year": year, "section": sector, "parcel_number": str(num)} if town: - dct['town'] = town + dct["town"] = town if owner: - dct['history_modifier'] = owner + dct["history_modifier"] = owner parcels.append(dct) return parcels diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 86e5b7f52..51cedbc9c 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2010-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -31,94 +31,114 @@ from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy from archaeological_operations import models from archaeological_operations import forms from archaeological_operations import wizards -from ishtar_common.forms import ClosingDateFormSelection, FinalForm, \ - FinalDeleteForm -from ishtar_common.models import get_current_profile, IshtarSiteProfile, \ - DocumentTemplate +from ishtar_common.forms import ClosingDateFormSelection, FinalForm, FinalDeleteForm +from ishtar_common.models import ( + get_current_profile, + IshtarSiteProfile, + DocumentTemplate, +) from ishtar_common.utils import put_session_message, check_rights_condition -from ishtar_common.views import gen_generate_doc, QAItemEditForm, \ - QABaseLockView, wizard_is_available, QAItemForm, IshtarMixin, \ - LoginRequiredMixin -from ishtar_common.views_item import get_item, show_item, revert_item, \ - new_qa_item +from ishtar_common.views import ( + gen_generate_doc, + QAItemEditForm, + QABaseLockView, + wizard_is_available, + QAItemForm, + IshtarMixin, + LoginRequiredMixin, +) +from ishtar_common.views_item import get_item, show_item, revert_item, new_qa_item from ishtar_common.wizards import SearchWizard def autocomplete_patriarche(request): - if (not request.user.has_perm('ishtar_common.view_operation', - models.Operation) - and not request.user.has_perm('ishtar_common.view_own_operation', - models.Operation) - and not request.user.ishtaruser.has_right( - 'operation_search', session=request.session)): - return HttpResponse(content_type='text/plain') - if not request.GET.get('term'): - return HttpResponse(content_type='text/plain') - q = request.GET.get('term') + if ( + not request.user.has_perm("ishtar_common.view_operation", models.Operation) + and not request.user.has_perm( + "ishtar_common.view_own_operation", models.Operation + ) + and not request.user.ishtaruser.has_right( + "operation_search", session=request.session + ) + ): + return HttpResponse(content_type="text/plain") + if not request.GET.get("term"): + return HttpResponse(content_type="text/plain") + q = request.GET.get("term") query = Q() - for q in q.split(' '): + for q in q.split(" "): query &= Q(code_patriarche__startswith=q) limit = 15 - operations = models.Operation.objects\ - .filter(query).order_by('code_patriarche')[:limit] - data = json.dumps([{'id': operation.code_patriarche, - 'value': operation.code_patriarche} - for operation in operations]) - return HttpResponse(data, content_type='text/plain') + operations = models.Operation.objects.filter(query).order_by("code_patriarche")[ + :limit + ] + data = json.dumps( + [ + {"id": operation.code_patriarche, "value": operation.code_patriarche} + for operation in operations + ] + ) + return HttpResponse(data, content_type="text/plain") def autocomplete_archaeologicalsite(request): - if (not request.user.has_perm( - 'archaeological_operations.view_archaeologicalsite', - models.ArchaeologicalSite) - and not request.user.has_perm( - 'archaeological_operations.view_own_archaeologicalsite', - models.ArchaeologicalSite)): - return HttpResponse(content_type='text/plain') - if not request.GET.get('term'): - return HttpResponse(content_type='text/plain') - q = request.GET.get('term') + if not request.user.has_perm( + "archaeological_operations.view_archaeologicalsite", models.ArchaeologicalSite + ) and not request.user.has_perm( + "archaeological_operations.view_own_archaeologicalsite", + models.ArchaeologicalSite, + ): + return HttpResponse(content_type="text/plain") + if not request.GET.get("term"): + return HttpResponse(content_type="text/plain") + q = request.GET.get("term") query = Q() - for q in q.split(' '): + for q in q.split(" "): qt = Q(reference__icontains=q) | Q(name__icontains=q) query = query & qt limit = 15 - sites = models.ArchaeologicalSite.objects.filter( - query).distinct().order_by('reference')[:limit] - data = json.dumps([{'id': site.pk, - 'value': str(site)[:60]} - for site in sites]) - return HttpResponse(data, content_type='text/plain') + sites = ( + models.ArchaeologicalSite.objects.filter(query) + .distinct() + .order_by("reference")[:limit] + ) + data = json.dumps([{"id": site.pk, "value": str(site)[:60]} for site in sites]) + return HttpResponse(data, content_type="text/plain") new_archaeologicalsite = new_qa_item( - models.ArchaeologicalSite, forms.ArchaeologicalSiteForm, many=True, - page_name=_("New archaeological site") + models.ArchaeologicalSite, + forms.ArchaeologicalSiteForm, + many=True, + page_name=_("New archaeological site"), ) def autocomplete_operation(request): # person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_common.view_operation', - models.Operation) + if ( + not request.user.has_perm("ishtar_common.view_operation", models.Operation) and not request.user.has_perm( - 'ishtar_common.view_own_operation', models.Operation) - and not request.user.ishtaruser.has_right( - 'operation_search', session=request.session)): - return HttpResponse(content_type='text/plain') - if not request.GET.get('term'): - return HttpResponse(content_type='text/plain') - q = request.GET.get('term') + "ishtar_common.view_own_operation", models.Operation + ) + and not request.user.ishtaruser.has_right( + "operation_search", session=request.session + ) + ): + return HttpResponse(content_type="text/plain") + if not request.GET.get("term"): + return HttpResponse(content_type="text/plain") + q = request.GET.get("term") query = Q() - for q in q.split(' '): + for q in q.split(" "): extra = Q(towns__name__icontains=q) | Q(common_name__icontains=q) try: int(q) extra = extra | Q(year=q) | Q(operation_code=q) except ValueError: pass - if settings.COUNTRY == 'fr': - if q.startswith('OA'): + if settings.COUNTRY == "fr": + if q.startswith("OA"): q = q[2:] try: int(q) @@ -128,80 +148,89 @@ def autocomplete_operation(request): query = query & extra limit = 15 operations = models.Operation.objects.filter(query).distinct()[:limit] - data = json.dumps([{'id': operation.pk, 'value': str(operation)} - for operation in operations]) - return HttpResponse(data, content_type='text/plain') + data = json.dumps( + [{"id": operation.pk, "value": str(operation)} for operation in operations] + ) + return HttpResponse(data, content_type="text/plain") def get_available_operation_code(request, year=None): if not request.user.has_perm( - 'ishtar_common.view_operation', models.Operation)\ - and not request.user.has_perm( - 'ishtar_common.view_own_operation', models.Operation): - return HttpResponse(content_type='text/plain') - data = json.dumps({'id': - models.Operation.get_available_operation_code(year)}) - return HttpResponse(data, content_type='text/plain') + "ishtar_common.view_operation", models.Operation + ) and not request.user.has_perm( + "ishtar_common.view_own_operation", models.Operation + ): + return HttpResponse(content_type="text/plain") + data = json.dumps({"id": models.Operation.get_available_operation_code(year)}) + return HttpResponse(data, content_type="text/plain") -get_operation = get_item(models.Operation, 'get_operation', 'operation', - search_form=forms.OperationSelect) +get_operation = get_item( + models.Operation, "get_operation", "operation", search_form=forms.OperationSelect +) -show_operation = show_item(models.Operation, 'operation') +show_operation = show_item(models.Operation, "operation") revert_operation = revert_item(models.Operation) get_administrativeactop = get_item( - models.AdministrativeAct, 'get_administrativeactop', 'administrativeactop', - base_request={"operation__pk__isnull": False}) + models.AdministrativeAct, + "get_administrativeactop", + "administrativeactop", + base_request={"operation__pk__isnull": False}, +) get_administrativeact = get_item( - models.AdministrativeAct, 'get_administrativeact', 'administrativeact') + models.AdministrativeAct, "get_administrativeact", "administrativeact" +) -show_administrativeact = show_item(models.AdministrativeAct, - 'administrativeact') +show_administrativeact = show_item(models.AdministrativeAct, "administrativeact") def dashboard_operation(request, *args, **kwargs): """ Operation dashboard """ - dct = {'dashboard': models.OperationDashboard()} - return render(request, 'ishtar/dashboards/dashboard_operation.html', dct) + dct = {"dashboard": models.OperationDashboard()} + return render(request, "ishtar/dashboards/dashboard_operation.html", dct) operation_search_wizard = wizards.OperationSearch.as_view( - [('general-operation_search', forms.OperationFormSelection)], + [("general-operation_search", forms.OperationFormSelection)], label=_("Operation search"), - url_name='operation_search',) + url_name="operation_search", +) wizard_steps = [ - ('filechoice-operation_creation', forms.OperationFormFileChoice), - ('general-operation_creation', forms.OperationFormGeneral), - ('judiciary-operation_creation', forms.CourtOrderedSeizureForm), - ('collaborators-operation_creation', forms.CollaboratorForm), - ('archaeologicalsite-operation_creation', forms.ArchaeologicalSiteFormSet), - ('preventive-operation_creation', forms.OperationFormPreventive), - ('preventivediag-operation_creation', forms.OperationFormPreventiveDiag), - ('townsgeneral-operation_creation', forms.TownFormset), - ('towns-operation_creation', forms.SelectedTownFormset), - ('parcelsgeneral-operation_creation', forms.SelectedParcelGeneralFormSet), - ('parcels-operation_creation', forms.SelectedParcelFormSet), - ('remains-operation_creation', forms.RemainForm), - ('periods-operation_creation', forms.PeriodForm), - ('relations-operation_creation', forms.RecordRelationsFormSet), - ('abstract-operation_creation', forms.OperationFormAbstract), - ('final-operation_creation', FinalForm)] + ("filechoice-operation_creation", forms.OperationFormFileChoice), + ("general-operation_creation", forms.OperationFormGeneral), + ("judiciary-operation_creation", forms.CourtOrderedSeizureForm), + ("collaborators-operation_creation", forms.CollaboratorForm), + ("archaeologicalsite-operation_creation", forms.ArchaeologicalSiteFormSet), + ("preventive-operation_creation", forms.OperationFormPreventive), + ("preventivediag-operation_creation", forms.OperationFormPreventiveDiag), + ("townsgeneral-operation_creation", forms.TownFormset), + ("towns-operation_creation", forms.SelectedTownFormset), + ("parcelsgeneral-operation_creation", forms.SelectedParcelGeneralFormSet), + ("parcels-operation_creation", forms.SelectedParcelFormSet), + ("remains-operation_creation", forms.RemainForm), + ("periods-operation_creation", forms.PeriodForm), + ("relations-operation_creation", forms.RecordRelationsFormSet), + ("abstract-operation_creation", forms.OperationFormAbstract), + ("final-operation_creation", FinalForm), +] def get_check_files_for_operation(other_check=None): def func(self): - if not get_current_profile().files or \ - not check_rights_condition(['view_file'])(self): + if not get_current_profile().files or not check_rights_condition(["view_file"])( + self + ): return False if not other_check: return True return other_check(self) + return func @@ -209,378 +238,456 @@ check_files_for_operation = get_check_files_for_operation() ope_crea_condition_dict = { - 'filechoice-operation_creation': check_files_for_operation, - 'judiciary-operation_creation': wizards.is_judiciary( - 'general-operation_creation', models.OperationType, 'operation_type', + "filechoice-operation_creation": check_files_for_operation, + "judiciary-operation_creation": wizards.is_judiciary( + "general-operation_creation", + models.OperationType, + "operation_type", + ), + "preventive-operation_creation": get_check_files_for_operation( + wizards.is_preventive( + "general-operation_creation", + models.OperationType, + "operation_type", + "prev_excavation", + ) + ), + "preventivediag-operation_creation": get_check_files_for_operation( + wizards.is_preventive( + "general-operation_creation", + models.OperationType, + "operation_type", + "arch_diagnostic", + ) + ), + "townsgeneral-operation_creation": wizards.has_associated_file( + "filechoice-operation_creation", negate=True + ), + "towns-operation_creation": wizards.has_associated_file( + "filechoice-operation_creation" + ), + "parcelsgeneral-operation_creation": wizards.has_associated_file( + "filechoice-operation_creation", negate=True + ), + "parcels-operation_creation": wizards.has_associated_file( + "filechoice-operation_creation" ), - 'preventive-operation_creation': - get_check_files_for_operation( - wizards.is_preventive('general-operation_creation', - models.OperationType, 'operation_type', - 'prev_excavation')), - 'preventivediag-operation_creation': - get_check_files_for_operation( - wizards.is_preventive('general-operation_creation', - models.OperationType, 'operation_type', - 'arch_diagnostic')), - 'townsgeneral-operation_creation': wizards.has_associated_file( - 'filechoice-operation_creation', negate=True), - 'towns-operation_creation': wizards.has_associated_file( - 'filechoice-operation_creation'), - 'parcelsgeneral-operation_creation': wizards.has_associated_file( - 'filechoice-operation_creation', negate=True), - 'parcels-operation_creation': wizards.has_associated_file( - 'filechoice-operation_creation'), } operation_creation_wizard = wizards.OperationWizard.as_view( wizard_steps, label=_("New operation"), condition_dict=ope_crea_condition_dict, - url_name='operation_creation',) + url_name="operation_creation", +) operation_modif_wizard_steps = [ - ('selec-operation_modification', forms.OperationFormSelection), - ('general-operation_modification', forms.OperationFormModifGeneral), - ('judiciary-operation_modification', forms.CourtOrderedSeizureForm), - ('collaborators-operation_modification', forms.CollaboratorForm), - ('archaeologicalsite-operation_modification', forms.ArchaeologicalSiteFormSet), - ('preventive-operation_modification', forms.OperationFormPreventive), - ('preventivediag-operation_modification', forms.OperationFormPreventiveDiag), - ('towns-operation_modification', forms.SelectedTownFormset), - ('townsgeneral-operation_modification', forms.TownFormset), - ('parcels-operation_modification', forms.SelectedParcelFormSet), - ('parcelsgeneral-operation_modification', forms.SelectedParcelGeneralFormSet), - ('remains-operation_modification', forms.RemainForm), - ('periods-operation_modification', forms.PeriodForm), - ('relations-operation_modification', forms.RecordRelationsFormSet), - ('abstract-operation_modification', forms.OperationFormAbstract), - ('final-operation_modification', FinalForm) + ("selec-operation_modification", forms.OperationFormSelection), + ("general-operation_modification", forms.OperationFormModifGeneral), + ("judiciary-operation_modification", forms.CourtOrderedSeizureForm), + ("collaborators-operation_modification", forms.CollaboratorForm), + ("archaeologicalsite-operation_modification", forms.ArchaeologicalSiteFormSet), + ("preventive-operation_modification", forms.OperationFormPreventive), + ("preventivediag-operation_modification", forms.OperationFormPreventiveDiag), + ("towns-operation_modification", forms.SelectedTownFormset), + ("townsgeneral-operation_modification", forms.TownFormset), + ("parcels-operation_modification", forms.SelectedParcelFormSet), + ("parcelsgeneral-operation_modification", forms.SelectedParcelGeneralFormSet), + ("remains-operation_modification", forms.RemainForm), + ("periods-operation_modification", forms.PeriodForm), + ("relations-operation_modification", forms.RecordRelationsFormSet), + ("abstract-operation_modification", forms.OperationFormAbstract), + ("final-operation_modification", FinalForm), ] ope_modif_condition_dict = { - 'preventive-operation_modification': - get_check_files_for_operation( - wizards.is_preventive('general-operation_modification', - models.OperationType, 'operation_type', - 'prev_excavation')), - 'preventivediag-operation_modification': - get_check_files_for_operation( - wizards.is_preventive('general-operation_modification', - models.OperationType, 'operation_type', - 'arch_diagnostic')), - 'judiciary-operation_modification': wizards.is_judiciary( - 'general-operation_modification', models.OperationType, 'operation_type', + "preventive-operation_modification": get_check_files_for_operation( + wizards.is_preventive( + "general-operation_modification", + models.OperationType, + "operation_type", + "prev_excavation", + ) + ), + "preventivediag-operation_modification": get_check_files_for_operation( + wizards.is_preventive( + "general-operation_modification", + models.OperationType, + "operation_type", + "arch_diagnostic", + ) + ), + "judiciary-operation_modification": wizards.is_judiciary( + "general-operation_modification", + models.OperationType, + "operation_type", + ), + "townsgeneral-operation_modification": wizards.has_associated_file( + "general-operation_modification", negate=True + ), + "towns-operation_modification": wizards.has_associated_file( + "general-operation_modification" + ), + "parcelsgeneral-operation_modification": wizards.has_associated_file( + "general-operation_modification", negate=True + ), + "parcels-operation_modification": wizards.has_associated_file( + "general-operation_modification" ), - 'townsgeneral-operation_modification': wizards.has_associated_file( - 'general-operation_modification', negate=True), - 'towns-operation_modification': wizards.has_associated_file( - 'general-operation_modification'), - 'parcelsgeneral-operation_modification': wizards.has_associated_file( - 'general-operation_modification', negate=True), - 'parcels-operation_modification': wizards.has_associated_file( - 'general-operation_modification'), - } operation_modification_wizard = wizards.OperationModificationWizard.as_view( operation_modif_wizard_steps, label=_("Operation modification"), condition_dict=ope_modif_condition_dict, - url_name='operation_modification',) + url_name="operation_modification", +) def operation_modify(request, pk): - if not wizard_is_available(operation_modification_wizard, request, - models.Operation, pk): + if not wizard_is_available( + operation_modification_wizard, request, models.Operation, pk + ): return HttpResponseRedirect("/") - wizard_url = 'operation_modification' + wizard_url = "operation_modification" wizards.OperationModificationWizard.session_set_value( - request, 'selec-' + wizard_url, 'pk', pk, reset=True) - return redirect(reverse(wizard_url, - kwargs={'step': 'general-' + wizard_url})) + request, "selec-" + wizard_url, "pk", pk, reset=True + ) + return redirect(reverse(wizard_url, kwargs={"step": "general-" + wizard_url})) def operation_add(request, file_id): operation_creation_wizard(request) wizards.OperationWizard.session_set_value( - request, 'filechoice-operation_creation', 'associated_file', - file_id, reset=True) - return redirect(reverse('operation_creation', - kwargs={'step': 'general-operation_creation'})) + request, "filechoice-operation_creation", "associated_file", file_id, reset=True + ) + return redirect( + reverse("operation_creation", kwargs={"step": "general-operation_creation"}) + ) + operation_closing_steps = [ - ('selec-operation_closing', forms.OperationFormSelection), - ('date-operation_closing', ClosingDateFormSelection), - ('final-operation_closing', forms.FinalOperationClosingForm)] + ("selec-operation_closing", forms.OperationFormSelection), + ("date-operation_closing", ClosingDateFormSelection), + ("final-operation_closing", forms.FinalOperationClosingForm), +] operation_closing_wizard = wizards.OperationClosingWizard.as_view( operation_closing_steps, label=_("Operation closing"), - url_name='operation_closing',) + url_name="operation_closing", +) operation_deletion_steps = [ - ('selec-operation_deletion', forms.OperationFormMultiSelection), - ('final-operation_deletion', forms.OperationDeletionForm) + ("selec-operation_deletion", forms.OperationFormMultiSelection), + ("final-operation_deletion", forms.OperationDeletionForm), ] operation_deletion_wizard = wizards.OperationDeletionWizard.as_view( operation_deletion_steps, label=_("Operation deletion"), - url_name='operation_deletion',) + url_name="operation_deletion", +) def operation_delete(request, pk): - if not wizard_is_available(operation_deletion_wizard, request, - models.Operation, pk): + if not wizard_is_available( + operation_deletion_wizard, request, models.Operation, pk + ): return HttpResponseRedirect("/") - wizard_url = 'operation_deletion' + wizard_url = "operation_deletion" wizards.OperationDeletionWizard.session_set_value( - request, 'selec-' + wizard_url, 'pks', pk, reset=True) - return redirect(reverse(wizard_url, - kwargs={'step': 'final-' + wizard_url})) + request, "selec-" + wizard_url, "pks", pk, reset=True + ) + return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) # archaeological sites + def site_extra_context(request, item): - return {'SITE_LABEL': IshtarSiteProfile.get_default_site_label()} + return {"SITE_LABEL": IshtarSiteProfile.get_default_site_label()} -get_site = get_item(models.ArchaeologicalSite, 'get_site', 'site', - search_form=forms.SiteSelect) -show_site = show_item( - models.ArchaeologicalSite, 'site', - extra_dct=site_extra_context +get_site = get_item( + models.ArchaeologicalSite, "get_site", "site", search_form=forms.SiteSelect ) +show_site = show_item(models.ArchaeologicalSite, "site", extra_dct=site_extra_context) revert_site = revert_item(models.ArchaeologicalSite) site_search_wizard = wizards.SiteSearch.as_view( - [('general-site_search', forms.SiteFormSelection)], - url_name='site_search', + [("general-site_search", forms.SiteFormSelection)], + url_name="site_search", ) site_creation_steps = [ - ('general-site_creation', forms.SiteForm), - ('towns-site_creation', forms.SiteTownFormset), - ('underwater-site_creation', forms.SiteUnderwaterForm), - ('final-site_creation', FinalForm) + ("general-site_creation", forms.SiteForm), + ("towns-site_creation", forms.SiteTownFormset), + ("underwater-site_creation", forms.SiteUnderwaterForm), + ("final-site_creation", FinalForm), ] site_creation_wizard = wizards.SiteWizard.as_view( site_creation_steps, - condition_dict={'underwater-site_creation': forms.check_underwater_module}, - url_name='site_creation', + condition_dict={"underwater-site_creation": forms.check_underwater_module}, + url_name="site_creation", ) site_modification_steps = [ - ('selec-site_modification', forms.SiteFormSelection), - ('general-site_modification', forms.SiteForm), - ('towns-site_modification', forms.SiteTownFormset), - ('underwater-site_modification', forms.SiteUnderwaterForm), - ('final-site_modification', FinalForm) + ("selec-site_modification", forms.SiteFormSelection), + ("general-site_modification", forms.SiteForm), + ("towns-site_modification", forms.SiteTownFormset), + ("underwater-site_modification", forms.SiteUnderwaterForm), + ("final-site_modification", FinalForm), ] site_modification_wizard = wizards.SiteModificationWizard.as_view( site_modification_steps, - condition_dict={ - 'underwater-site_modification': forms.check_underwater_module}, - url_name='site_modification', + condition_dict={"underwater-site_modification": forms.check_underwater_module}, + url_name="site_modification", ) def site_modify(request, pk): - if not wizard_is_available(site_modification_wizard, request, - models.ArchaeologicalSite, pk): + if not wizard_is_available( + site_modification_wizard, request, models.ArchaeologicalSite, pk + ): return HttpResponseRedirect("/") - wizard_url = 'site_modification' + wizard_url = "site_modification" wizards.SiteModificationWizard.session_set_value( - request, 'selec-' + wizard_url, 'pk', pk, reset=True) - return redirect(reverse(wizard_url, - kwargs={'step': 'general-' + wizard_url})) + request, "selec-" + wizard_url, "pk", pk, reset=True + ) + return redirect(reverse(wizard_url, kwargs={"step": "general-" + wizard_url})) site_deletion_steps = [ - ('selec-site_deletion', forms.SiteFormMultiSelection), - ('final-site_deletion', FinalDeleteForm) + ("selec-site_deletion", forms.SiteFormMultiSelection), + ("final-site_deletion", FinalDeleteForm), ] site_deletion_wizard = wizards.SiteDeletionWizard.as_view( site_deletion_steps, label=_("Site deletion"), - url_name='site_deletion',) + url_name="site_deletion", +) def site_delete(request, pk): - if not wizard_is_available(site_deletion_wizard, request, - models.ArchaeologicalSite, pk): + if not wizard_is_available( + site_deletion_wizard, request, models.ArchaeologicalSite, pk + ): return HttpResponseRedirect("/") - wizard_url = 'site_deletion' + wizard_url = "site_deletion" wizards.SiteDeletionWizard.session_set_value( - request, 'selec-' + wizard_url, 'pks', pk, reset=True) - return redirect(reverse(wizard_url, - kwargs={'step': 'final-' + wizard_url})) - -operation_administrativeactop_search_wizard = wizards.SearchWizard.as_view([ - ('general-operation_administrativeactop_search', - forms.AdministrativeActOpeFormSelection)], + request, "selec-" + wizard_url, "pks", pk, reset=True + ) + return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) + + +operation_administrativeactop_search_wizard = wizards.SearchWizard.as_view( + [ + ( + "general-operation_administrativeactop_search", + forms.AdministrativeActOpeFormSelection, + ) + ], label=_("Administrative act search"), - url_name='operation_administrativeactop_search',) + url_name="operation_administrativeactop_search", +) administrativeactop_steps = [ - ('selec-operation_administrativeactop', forms.OperationFormSelection), - ('administrativeact-operation_administrativeactop', - forms.AdministrativeActOpeForm), - ('final-operation_administrativeactop', FinalForm)] - - -operation_administrativeactop_wizard = \ - wizards.OperationAdministrativeActWizard.as_view( - administrativeactop_steps, - label=_("Operation: new administrative act"), - url_name='operation_administrativeactop',) - -operation_administrativeactop_modification_wizard = \ - wizards.OperationEditAdministrativeActWizard.as_view([ - ('selec-operation_administrativeactop_modification', - forms.AdministrativeActOpeFormSelection), - ('administrativeact-operation_administrativeactop_modification', - forms.AdministrativeActOpeModifForm), - ('final-operation_administrativeactop_modification', FinalForm)], + ("selec-operation_administrativeactop", forms.OperationFormSelection), + ("administrativeact-operation_administrativeactop", forms.AdministrativeActOpeForm), + ("final-operation_administrativeactop", FinalForm), +] + + +operation_administrativeactop_wizard = wizards.OperationAdministrativeActWizard.as_view( + administrativeactop_steps, + label=_("Operation: new administrative act"), + url_name="operation_administrativeactop", +) + +operation_administrativeactop_modification_wizard = ( + wizards.OperationEditAdministrativeActWizard.as_view( + [ + ( + "selec-operation_administrativeactop_modification", + forms.AdministrativeActOpeFormSelection, + ), + ( + "administrativeact-operation_administrativeactop_modification", + forms.AdministrativeActOpeModifForm, + ), + ("final-operation_administrativeactop_modification", FinalForm), + ], label=_("Operation: administrative act modification"), - url_name='operation_administrativeactop_modification',) + url_name="operation_administrativeactop_modification", + ) +) def operation_administrativeactop_modify(request, pk): if not wizard_is_available( - operation_administrativeactop_modification_wizard, request, - models.AdministrativeAct, pk): + operation_administrativeactop_modification_wizard, + request, + models.AdministrativeAct, + pk, + ): return HttpResponseRedirect("/") - wizard_url = 'operation_administrativeactop_modification' + wizard_url = "operation_administrativeactop_modification" wizards.OperationEditAdministrativeActWizard.session_set_value( - request, 'selec-' + wizard_url, 'pk', pk, reset=True) + request, "selec-" + wizard_url, "pk", pk, reset=True + ) return redirect( - reverse(wizard_url, kwargs={'step': 'administrativeact-' + wizard_url})) - - -operation_administrativeactop_deletion_wizard = \ - wizards.AdministrativeActDeletionWizard.as_view([ - ('selec-operation_administrativeactop_deletion', - forms.AdministrativeActOpeFormSelection), - ('final-operation_administrativeactop_deletion', - forms.FinalAdministrativeActDeleteForm)], + reverse(wizard_url, kwargs={"step": "administrativeact-" + wizard_url}) + ) + + +operation_administrativeactop_deletion_wizard = ( + wizards.AdministrativeActDeletionWizard.as_view( + [ + ( + "selec-operation_administrativeactop_deletion", + forms.AdministrativeActOpeFormSelection, + ), + ( + "final-operation_administrativeactop_deletion", + forms.FinalAdministrativeActDeleteForm, + ), + ], label=_("Operation: administrative act deletion"), - url_name='operation_administrativeactop_deletion',) + url_name="operation_administrativeactop_deletion", + ) +) def operation_administrativeactop_delete(request, pk): if not wizard_is_available( - operation_administrativeactop_deletion_wizard, request, - models.AdministrativeAct, pk): + operation_administrativeactop_deletion_wizard, + request, + models.AdministrativeAct, + pk, + ): return HttpResponseRedirect("/") - wizard_url = 'operation_administrativeactop_deletion' + wizard_url = "operation_administrativeactop_deletion" wizards.AdministrativeActDeletionWizard.session_set_value( - request, 'selec-' + wizard_url, 'pk', pk, reset=True) - return redirect( - reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) - - -administrativact_register_wizard = SearchWizard.as_view([ - ('general-administrativact_register', - forms.AdministrativeActRegisterFormSelection)], - label=pgettext_lazy('admin act register', "Register"), - url_name='administrativact_register',) + request, "selec-" + wizard_url, "pk", pk, reset=True + ) + return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) + + +administrativact_register_wizard = SearchWizard.as_view( + [ + ( + "general-administrativact_register", + forms.AdministrativeActRegisterFormSelection, + ) + ], + label=pgettext_lazy("admin act register", "Register"), + url_name="administrativact_register", +) generatedoc_administrativeactop = gen_generate_doc(models.AdministrativeAct) def administrativeactfile_document( - request, file=False, treatment=False, treatment_file=False): + request, file=False, treatment=False, treatment_file=False +): search_form = forms.AdministrativeActOpeFormSelection - document_type = 'O' + document_type = "O" if file: - from archaeological_files.forms import \ - AdministrativeActFileFormSelection + from archaeological_files.forms import AdministrativeActFileFormSelection + search_form = AdministrativeActFileFormSelection - document_type = 'F' + document_type = "F" elif treatment: - from archaeological_finds.forms import \ - AdministrativeActTreatmentFormSelection + from archaeological_finds.forms import AdministrativeActTreatmentFormSelection + search_form = AdministrativeActTreatmentFormSelection - document_type = 'T' + document_type = "T" elif treatment_file: - from archaeological_finds.forms import \ - AdministrativeActTreatmentFileFormSelection + from archaeological_finds.forms import ( + AdministrativeActTreatmentFileFormSelection, + ) + search_form = AdministrativeActTreatmentFileFormSelection - document_type = 'TF' + document_type = "TF" - if not request.user.has_perm('view_administrativeact', - models.AdministrativeAct): - return HttpResponse(content_type='text/plain') + if not request.user.has_perm("view_administrativeact", models.AdministrativeAct): + return HttpResponse(content_type="text/plain") dct = {} DocumentGenerationAdminActForm = forms.DocumentGenerationAdminActForm if request.POST: - dct['search_form'] = search_form(request.POST) - dct['template_form'] = DocumentGenerationAdminActForm( - document_type=document_type) + dct["search_form"] = search_form(request.POST) + dct["template_form"] = DocumentGenerationAdminActForm( + document_type=document_type + ) c_object = None try: - if dct['search_form'].is_valid(): - c_object = \ - DocumentGenerationAdminActForm._associated_model\ - .objects.get(pk=dct['search_form'].cleaned_data.get('pk')) + if dct["search_form"].is_valid(): + c_object = DocumentGenerationAdminActForm._associated_model.objects.get( + pk=dct["search_form"].cleaned_data.get("pk") + ) except DocumentGenerationAdminActForm._associated_model.DoesNotExist: pass if c_object: - dct['template_form'] = DocumentGenerationAdminActForm( - request.POST, document_type=document_type, obj=c_object) - if dct['template_form'].is_valid(): + dct["template_form"] = DocumentGenerationAdminActForm( + request.POST, document_type=document_type, obj=c_object + ) + if dct["template_form"].is_valid(): try: return generatedoc_administrativeactop( request, - dct['search_form'].cleaned_data.get('pk'), - dct['template_form'].cleaned_data.get( - 'document_template')) + dct["search_form"].cleaned_data.get("pk"), + dct["template_form"].cleaned_data.get("document_template"), + ) except TemplateSyntaxError: - dct['search_form'] = search_form() + dct["search_form"] = search_form() try: - template = DocumentTemplate.objects.get(pk=dct[ - 'template_form'].cleaned_data.get( - 'document_template')).name + template = DocumentTemplate.objects.get( + pk=dct["template_form"].cleaned_data.get( + "document_template" + ) + ).name except DocumentTemplate.DoesNotExist: template = "" - dct['template_form'] = DocumentGenerationAdminActForm( - document_type=document_type) - dct['template_error'] = str(_( - "Syntax error on the source template \"{}\" - " - "contact your administrator and ask him to check " - "the syntax of this document.")).format(template) + dct["template_form"] = DocumentGenerationAdminActForm( + document_type=document_type + ) + dct["template_error"] = str( + _( + 'Syntax error on the source template "{}" - ' + "contact your administrator and ask him to check " + "the syntax of this document." + ) + ).format(template) else: - dct['search_form'] = search_form() - dct['template_form'] = DocumentGenerationAdminActForm( - document_type=document_type) - return render(request, 'ishtar/administrativeact_document.html', dct) + dct["search_form"] = search_form() + dct["template_form"] = DocumentGenerationAdminActForm( + document_type=document_type + ) + return render(request, "ishtar/administrativeact_document.html", dct) def autocomplete_administrativeact(request): - if (not request.user.has_perm( - 'archaeological_operations.view_administrativeact', - models.AdministrativeAct) - and not request.user.has_perm( - 'archaeological_operations.view_own_administrativeact', - models.AdministrativeAct)): - return HttpResponse(content_type='text/plain') - if not request.GET.get('term'): - return HttpResponse(content_type='text/plain') - q = request.GET.get('term') + if not request.user.has_perm( + "archaeological_operations.view_administrativeact", models.AdministrativeAct + ) and not request.user.has_perm( + "archaeological_operations.view_own_administrativeact", models.AdministrativeAct + ): + return HttpResponse(content_type="text/plain") + if not request.GET.get("term"): + return HttpResponse(content_type="text/plain") + q = request.GET.get("term") query = Q() - for q in q.split(' '): + for q in q.split(" "): qt = Q(act_type__label__icontains=q) | Q(towns_label=q) try: if len(q) == 4: @@ -590,25 +697,33 @@ def autocomplete_administrativeact(request): pass query = query & qt limit = 15 - items = models.AdministrativeAct.objects.filter( - query).order_by('year', 'index').distinct()[:limit] - data = json.dumps([{'id': item.pk, 'value': str(item)[:80] + " (...)"} - for item in items]) - return HttpResponse(data, content_type='text/plain') + items = ( + models.AdministrativeAct.objects.filter(query) + .order_by("year", "index") + .distinct()[:limit] + ) + data = json.dumps( + [{"id": item.pk, "value": str(item)[:80] + " (...)"} for item in items] + ) + return HttpResponse(data, content_type="text/plain") def reset_wizards(request): for wizard_class, url_name in ( - (wizards.OperationWizard, 'operation_creation'), - (wizards.OperationModificationWizard, 'operation_modification'), - (wizards.OperationClosingWizard, 'operation_closing'), - (wizards.OperationDeletionWizard, 'operation_deletion_wizard'), - (wizards.OperationAdministrativeActWizard, - 'operation_administrativeactop'), - (wizards.OperationEditAdministrativeActWizard, - 'operation_administrativeactop_modification'), - (wizards.AdministrativeActDeletionWizard, - 'operation_administrativeactop_deletion'),): + (wizards.OperationWizard, "operation_creation"), + (wizards.OperationModificationWizard, "operation_modification"), + (wizards.OperationClosingWizard, "operation_closing"), + (wizards.OperationDeletionWizard, "operation_deletion_wizard"), + (wizards.OperationAdministrativeActWizard, "operation_administrativeactop"), + ( + wizards.OperationEditAdministrativeActWizard, + "operation_administrativeactop_modification", + ), + ( + wizards.AdministrativeActDeletionWizard, + "operation_administrativeactop_deletion", + ), + ): wizard_class.session_reset(request, url_name) @@ -628,7 +743,7 @@ class QASiteLockView(QABaseLockView): class QAOperationdDuplicateFormView(QAItemForm): - template_name = 'ishtar/forms/qa_operation_duplicate.html' + template_name = "ishtar/forms/qa_operation_duplicate.html" model = models.Operation page_name = _("Duplicate") form_class = forms.QAOperationDuplicateForm @@ -636,7 +751,7 @@ class QAOperationdDuplicateFormView(QAItemForm): def get_form_kwargs(self): kwargs = super(QAOperationdDuplicateFormView, self).get_form_kwargs() - kwargs['user'] = self.request.user + kwargs["user"] = self.request.user return kwargs def form_valid(self, form): @@ -644,23 +759,21 @@ class QAOperationdDuplicateFormView(QAItemForm): return HttpResponseRedirect(reverse("success")) def get_context_data(self, **kwargs): - data = super(QAOperationdDuplicateFormView, self).get_context_data( - **kwargs) - data['action_name'] = _("Duplicate") + data = super(QAOperationdDuplicateFormView, self).get_context_data(**kwargs) + data["action_name"] = _("Duplicate") return data class QAArchaeologicalSiteDuplicateFormView(QAItemForm): - template_name = 'ishtar/forms/qa_site_duplicate.html' + template_name = "ishtar/forms/qa_site_duplicate.html" model = models.ArchaeologicalSite page_name = _("Duplicate") form_class = forms.QAArchaeologicalSiteDuplicateForm base_url = "site-qa-duplicate" def get_form_kwargs(self): - kwargs = super(QAArchaeologicalSiteDuplicateFormView, - self).get_form_kwargs() - kwargs['user'] = self.request.user + kwargs = super(QAArchaeologicalSiteDuplicateFormView, self).get_form_kwargs() + kwargs["user"] = self.request.user return kwargs def form_valid(self, form): @@ -668,9 +781,10 @@ class QAArchaeologicalSiteDuplicateFormView(QAItemForm): return HttpResponseRedirect(reverse("success")) def get_context_data(self, **kwargs): - data = super(QAArchaeologicalSiteDuplicateFormView, - self).get_context_data(**kwargs) - data['action_name'] = _("Duplicate") + data = super(QAArchaeologicalSiteDuplicateFormView, self).get_context_data( + **kwargs + ) + data["action_name"] = _("Duplicate") return data @@ -683,30 +797,36 @@ class GenerateStatsOperation(IshtarMixin, LoginRequiredMixin, RedirectView): model = models.Operation def get_redirect_url(self, *args, **kwargs): - return reverse('display-item', - args=[self.model.SLUG, self.item.pk]) + "#statistics" + return ( + reverse("display-item", args=[self.model.SLUG, self.item.pk]) + + "#statistics" + ) def get(self, request, *args, **kwargs): - self.item = self.model.objects.get(pk=kwargs['pk']) - self.item._get_or_set_stats('_nb_acts', update=True) - self.item._get_or_set_stats('_nb_indexed_acts', update=True) - self.item._get_or_set_stats('_nb_context_records', update=True) - self.item._get_or_set_stats('_nb_context_records_by_type', update=True, - expected_type=list) - self.item._get_or_set_stats('_nb_context_records_by_periods', - update=True, expected_type=list) - self.item._get_or_set_stats('_nb_finds', update=True) - self.item._get_or_set_stats('_nb_finds_by_material_type', update=True, - expected_type=list) - self.item._get_or_set_stats('_nb_finds_by_types', update=True, - expected_type=list) - self.item._get_or_set_stats('_nb_finds_by_periods', update=True, - expected_type=list) - self.item._get_or_set_stats('_nb_documents', update=True) - self.item._get_or_set_stats('_nb_documents_by_types', update=True, - expected_type=list) - self.item._get_or_set_stats('_nb_stats_finds_by_ue', update=True) + self.item = self.model.objects.get(pk=kwargs["pk"]) + self.item._get_or_set_stats("_nb_acts", update=True) + self.item._get_or_set_stats("_nb_indexed_acts", update=True) + self.item._get_or_set_stats("_nb_context_records", update=True) + self.item._get_or_set_stats( + "_nb_context_records_by_type", update=True, expected_type=list + ) + self.item._get_or_set_stats( + "_nb_context_records_by_periods", update=True, expected_type=list + ) + self.item._get_or_set_stats("_nb_finds", update=True) + self.item._get_or_set_stats( + "_nb_finds_by_material_type", update=True, expected_type=list + ) + self.item._get_or_set_stats( + "_nb_finds_by_types", update=True, expected_type=list + ) + self.item._get_or_set_stats( + "_nb_finds_by_periods", update=True, expected_type=list + ) + self.item._get_or_set_stats("_nb_documents", update=True) + self.item._get_or_set_stats( + "_nb_documents_by_types", update=True, expected_type=list + ) + self.item._get_or_set_stats("_nb_stats_finds_by_ue", update=True) return super(GenerateStatsOperation, self).get(request, *args, **kwargs) - - diff --git a/archaeological_operations/widgets.py b/archaeological_operations/widgets.py index 247fafba5..1494d0c14 100644 --- a/archaeological_operations/widgets.py +++ b/archaeological_operations/widgets.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2013-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -28,11 +28,11 @@ from ishtar_common.utils import ugettext_lazy as _ class ParcelWidget(widgets.MultiWidget): def __init__(self, attrs=None): if not attrs: - attrs = {'class': 'widget-parcel'} - elif 'class' not in attrs: - attrs['class'] = 'widget-parcel' + attrs = {"class": "widget-parcel"} + elif "class" not in attrs: + attrs["class"] = "widget-parcel" else: - attrs['class'] += ' widget-parcel' + attrs["class"] += " widget-parcel" _widgets = ( widgets.TextInput(attrs=attrs), widgets.TextInput(attrs=attrs), @@ -46,7 +46,7 @@ class ParcelWidget(widgets.MultiWidget): return [None, None] def format_output(self, rendered_widgets): - return ' / '.join(rendered_widgets) + return " / ".join(rendered_widgets) class SelectParcelWidget(widgets.TextInput): @@ -56,7 +56,9 @@ class SelectParcelWidget(widgets.TextInput): <div class="input-group-append"> <button class='input-group-text btn btn-success' name='formset_add' value='add'>{}</button> - </div>""".format(render, _("Add")) + </div>""".format( + render, _("Add") + ) return mark_safe(html) @@ -64,11 +66,12 @@ class OAWidget(forms.TextInput): def render(self, name, value, attrs=None, renderer=None): if not value: value = "" - final_attrs = flatatt( - self.build_attrs(attrs, {'name': name, 'value': value})) - dct = {'final_attrs': final_attrs, - 'id': attrs['id'], - "safe_id": attrs['id'].replace('-', '_')} - t = loader.get_template('ishtar/blocks/OAWidget.html') + final_attrs = flatatt(self.build_attrs(attrs, {"name": name, "value": value})) + dct = { + "final_attrs": final_attrs, + "id": attrs["id"], + "safe_id": attrs["id"].replace("-", "_"), + } + t = loader.get_template("ishtar/blocks/OAWidget.html") rendered = t.render(dct) return mark_safe(rendered) diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index c76bbd313..a58e7437d 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2012-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> @@ -31,8 +31,13 @@ from archaeological_operations import models from .forms import GenerateDocForm from ishtar_common.forms import reverse_lazy from ishtar_common.models import get_current_profile -from ishtar_common.wizards import Wizard, ClosingWizard, DeletionWizard, \ - SearchWizard, MultipleDeletionWizard +from ishtar_common.wizards import ( + Wizard, + ClosingWizard, + DeletionWizard, + SearchWizard, + MultipleDeletionWizard, +) logger = logging.getLogger(__name__) @@ -43,67 +48,63 @@ class OperationSearch(SearchWizard): class OperationWizard(Wizard): model = models.Operation - object_parcel_type = 'operation' - parcel_step_key = 'parcels' - relations_step_key = 'relations' + object_parcel_type = "operation" + parcel_step_key = "parcels" + relations_step_key = "relations" # step including the current(s) town(s) - town_step_keys = ['towns-', 'townsgeneral-'] - town_input_id = 'town' # input id of the current(s) town(s) + town_step_keys = ["towns-", "townsgeneral-"] + town_input_id = "town" # input id of the current(s) town(s) multi_towns = False # true if current town are multi valued towns_formset = True # true if towns are managed with formset - wizard_done_window = reverse_lazy('show-operation') + wizard_done_window = reverse_lazy("show-operation") redirect_url = "operation_modification" def get_template_names(self): templates = super(OperationWizard, self).get_template_names() current_step = self.steps.current if current_step.startswith(self.parcel_step_key): - templates = ['ishtar/wizard/parcels_wizard.html'] + templates + templates = ["ishtar/wizard/parcels_wizard.html"] + templates elif current_step.startswith(self.relations_step_key): - templates = ['ishtar/wizard/relations_wizard.html'] + templates + templates = ["ishtar/wizard/relations_wizard.html"] + templates return templates def get_current_file(self): step = self.steps.current if not step: return - file_form_key = 'general-' + self.url_name - if self.url_name == 'operation_creation': - file_form_key = 'filechoice-' + self.url_name + file_form_key = "general-" + self.url_name + if self.url_name == "operation_creation": + file_form_key = "filechoice-" + self.url_name file_id = self.session_get_value(file_form_key, "associated_file") try: idx = int(file_id) current_file = File.objects.get(pk=idx) return current_file - except(TypeError, ValueError, ObjectDoesNotExist): + except (TypeError, ValueError, ObjectDoesNotExist): pass def get_reminder(self): archaeological_file = self.get_current_file() if archaeological_file: - return ((_("Archaeological file"), - str(archaeological_file)),) + return ((_("Archaeological file"), str(archaeological_file)),) def get_context_data(self, form, **kwargs): """ Return extra context for templates """ - context = super(OperationWizard, self).get_context_data(form, - **kwargs) + context = super(OperationWizard, self).get_context_data(form, **kwargs) step = self.steps.current - if step.startswith('towns'): - context['TOWNS'] = self.get_towns() - elif step.startswith('parcels-') and self.get_current_file(): + if step.startswith("towns"): + context["TOWNS"] = self.get_towns() + elif step.startswith("parcels-") and self.get_current_file(): # if a file is associated to the operation add the button "Add all" - context['add_all'] = True - if step.startswith('parcels') and \ - hasattr(self, 'automatic_parcel_association'): - context['automatic_parcel_association'] = \ - self.automatic_parcel_association + context["add_all"] = True + if step.startswith("parcels") and hasattr(self, "automatic_parcel_association"): + context["automatic_parcel_association"] = self.automatic_parcel_association # reminder of the current file reminder = self.get_reminder() if reminder: - context['reminders'] = reminder + context["reminders"] = reminder return context def get_towns(self): @@ -127,8 +128,9 @@ class OperationWizard(Wizard): operation = self.get_current_object() if operation: for parcel in operation.parcels.all(): - current_parcels.append((parcel.town, parcel.section, - parcel.parcel_number)) + current_parcels.append( + (parcel.town, parcel.section, parcel.parcel_number) + ) parcels.append((parcel.pk, parcel.short_label)) try: for parcel in file.parcels.all(): @@ -159,27 +161,31 @@ class OperationWizard(Wizard): except KeyError: raise Http404() # manage the dynamic choice of towns - if step.startswith('towns') and hasattr(form, 'management_form'): - data['TOWNS'] = self.get_towns() - elif step.startswith(self.parcel_step_key) \ - and hasattr(form, 'management_form'): + if step.startswith("towns") and hasattr(form, "management_form"): + data["TOWNS"] = self.get_towns() + elif step.startswith(self.parcel_step_key) and hasattr(form, "management_form"): file = self.get_current_file() if file: - data['PARCELS'] = self.get_available_parcels(file) + data["PARCELS"] = self.get_available_parcels(file) else: town_ids = [] for town_step_key in self.town_step_keys: town_form_key = town_step_key + self.url_name - town_ids = self.session_get_value( - town_form_key, self.town_input_id, - multi=self.towns_formset, - multi_value=self.multi_towns) or [] + town_ids = ( + self.session_get_value( + town_form_key, + self.town_input_id, + multi=self.towns_formset, + multi_value=self.multi_towns, + ) + or [] + ) if town_ids: towns = [] if type(town_ids) == str: town_ids = [town_ids] for ids in town_ids: - for d in ids.split(','): + for d in ids.split(","): if d: towns.append(d) town_ids = towns @@ -193,7 +199,7 @@ class OperationWizard(Wizard): towns.append((town.pk, str(town))) except (ValueError, ObjectDoesNotExist): pass - data['TOWNS'] = sorted(towns, key=lambda x: x[1]) + data["TOWNS"] = sorted(towns, key=lambda x: x[1]) data = data or None form = super(OperationWizard, self).get_form(step, data, files) return form @@ -204,18 +210,24 @@ class OperationWizard(Wizard): """ datas = super(OperationWizard, self).get_formated_datas(forms) # if the general town form is used the advertissement is relevant - has_no_af = [form.prefix for form in forms - if form.prefix == 'townsgeneral-operation'] and True + has_no_af = [ + form.prefix for form in forms if form.prefix == "townsgeneral-operation" + ] and True if has_no_af: - datas = [[ - _("Warning: No Archaeological File is provided. " - "If you have forget it return to the first step."), []]]\ - + datas + datas = [ + [ + _( + "Warning: No Archaeological File is provided. " + "If you have forget it return to the first step." + ), + [], + ] + ] + datas return datas def get_form_initial(self, step, data=None): initial = super(OperationWizard, self).get_form_initial(step) - if step == 'general-operation_creation': + if step == "general-operation_creation": initial.update(self._copy_from_associated_field()) return initial @@ -239,17 +251,19 @@ class OperationWizard(Wizard): file = self.get_current_file() if not file: return initial - keys = ((('in_charge', 'pk'), 'in_charge'), - (('name',), 'common_name'), - (('total_surface',), 'surface'), - ) + keys = ( + (("in_charge", "pk"), "in_charge"), + (("name",), "common_name"), + (("total_surface",), "surface"), + ) initial.update(self.__copy_fields(file, keys)) if file.is_preventive(): return initial - keys = ((('scientist', 'pk'), 'scientist'), - (('requested_operation_type', 'pk'), 'operation_type'), - (('organization', 'pk'), 'operator'), - ) + keys = ( + (("scientist", "pk"), "scientist"), + (("requested_operation_type", "pk"), "operation_type"), + (("organization", "pk"), "operator"), + ) initial.update(self.__copy_fields(file, keys)) return initial @@ -258,7 +272,7 @@ class OperationWizard(Wizard): post_data = request.POST.copy() # add all parcel from available in the archaeological file - if not post_data.get('add_all_parcels', None): + if not post_data.get("add_all_parcels", None): return super(OperationWizard, self).post(*args, **kwargs) file = self.get_current_file() @@ -269,12 +283,12 @@ class OperationWizard(Wizard): idx = -1 # remove non relevant deleted keys for k in post_data.keys(): - if k.startswith(parcel_form_key) and k.endswith('-DELETE'): + if k.startswith(parcel_form_key) and k.endswith("-DELETE"): post_data.pop(k) for idx, parcel in enumerate(self.get_available_parcels(file)): parcel_pk, parcel_name = parcel post_data["%s-%d-parcel" % (parcel_form_key, idx)] = parcel_pk - post_data[parcel_form_key + '-TOTAL_FORMS'] = idx + 2 + post_data[parcel_form_key + "-TOTAL_FORMS"] = idx + 2 request.POST = post_data return super(OperationWizard, self).post(*args, **kwargs) @@ -284,11 +298,12 @@ class OperationWizard(Wizard): class OperationModificationWizard(OperationWizard): modification = True - filter_owns = {'selec-operation_modification': ['pk']} + filter_owns = {"selec-operation_modification": ["pk"]} def get_form_kwargs(self, step, **kwargs): kwargs = super(OperationModificationWizard, self).get_form_kwargs( - step, **kwargs) + step, **kwargs + ) if step != "relations-operation_modification": return kwargs kwargs["left_record"] = self.get_current_object() @@ -297,35 +312,47 @@ class OperationModificationWizard(OperationWizard): class OperationClosingWizard(ClosingWizard): model = models.Operation - fields = ['year', 'operation_code', 'operation_type', 'associated_file', - 'in_charge', 'scientist', 'start_date', 'excavation_end_date', - 'comment', 'towns', 'remains'] + fields = [ + "year", + "operation_code", + "operation_type", + "associated_file", + "in_charge", + "scientist", + "start_date", + "excavation_end_date", + "comment", + "towns", + "remains", + ] class OperationDeletionWizard(MultipleDeletionWizard): model = models.Operation fields = OperationClosingWizard.fields - filter_owns = {'selec-operation_deletion': ['pks']} + filter_owns = {"selec-operation_deletion": ["pks"]} redirect_url = "operation_deletion" class OperationAdministrativeActWizard(OperationWizard): edit = False - wizard_done_window = reverse_lazy('show-administrativeact') - current_obj_slug = 'administrativeactop' - ref_object_key = 'operation' + wizard_done_window = reverse_lazy("show-administrativeact") + current_obj_slug = "administrativeactop" + ref_object_key = "operation" redirect_url = "operation_administrativeactop_modification" def get_reminder(self): - form_key = 'selec-' + self.url_name - if self.url_name.endswith('_administrativeactop'): + form_key = "selec-" + self.url_name + if self.url_name.endswith("_administrativeactop"): # modification and deletion are suffixed with '_modification' # and '_deletion' so it is creation operation_id = self.session_get_value(form_key, "pk") try: return ( - (_("Operation"), - str(models.Operation.objects.get(pk=operation_id))), + ( + _("Operation"), + str(models.Operation.objects.get(pk=operation_id)), + ), ) except models.Operation.DoesNotExist: return @@ -340,35 +367,37 @@ class OperationAdministrativeActWizard(OperationWizard): return def get_extra_model(self, dct, m2m, form_list): - dct['history_modifier'] = self.request.user + dct["history_modifier"] = self.request.user return dct def get_context_data(self, form, **kwargs): # manage document generation - context = super(OperationAdministrativeActWizard, - self).get_context_data(form, **kwargs) + context = super(OperationAdministrativeActWizard, self).get_context_data( + form, **kwargs + ) step = self.steps.current - if step.startswith('final-'): - general_form_key = 'administrativeact-' + self.url_name + if step.startswith("final-"): + general_form_key = "administrativeact-" + self.url_name act_type = None try: act_type = models.ActType.objects.get( - pk=self.session_get_value(general_form_key, "act_type")) + pk=self.session_get_value(general_form_key, "act_type") + ) except models.ActType.DoesNotExist: pass if act_type and act_type.associated_template.count(): - context['extra_form'] = GenerateDocForm( - choices=act_type.associated_template.all()) + context["extra_form"] = GenerateDocForm( + choices=act_type.associated_template.all() + ) return context def get_associated_item(self, dct): return self.get_current_object() - def save_model(self, dct, m2m, whole_associated_models, form_list, - return_object): - dct['history_modifier'] = self.request.user - if 'pk' in dct: - dct.pop('pk') + def save_model(self, dct, m2m, whole_associated_models, form_list, return_object): + dct["history_modifier"] = self.request.user + if "pk" in dct: + dct.pop("pk") if self.edit: admact = self.get_current_object() for k in dct: @@ -382,11 +411,15 @@ class OperationAdministrativeActWizard(OperationWizard): dct[self.ref_object_key] = associated_item admact = models.AdministrativeAct(**dct) admact.save() - dct['item'] = admact + dct["item"] = admact # check if a doc generation is required - keys = [self.storage.prefix, 'step_data', 'final-' + self.url_name, - 'doc_generation'] + keys = [ + self.storage.prefix, + "step_data", + "final-" + self.url_name, + "doc_generation", + ] r = self.request.session for k in keys: if k in r and r[k]: @@ -396,21 +429,27 @@ class OperationAdministrativeActWizard(OperationWizard): if k == keys[-1]: # the whole list as been traversed wizard_done_window = str(self.wizard_done_window) if wizard_done_window: - dct['wizard_done_window'] = wizard_done_window + dct["wizard_done_window"] = wizard_done_window # redirect to the generated doc if r and type(r) in (tuple, list) and r[0]: - dct['redirect'] = reverse('generatedoc-administrativeactop', - args=[admact.pk, r[0]]) + dct["redirect"] = reverse( + "generatedoc-administrativeactop", args=[admact.pk, r[0]] + ) # make the new object a default - ishtaruser = self.request.user.ishtaruser \ - if hasattr(self.request.user, 'ishtaruser') else None - if ishtaruser and ishtaruser.current_profile \ - and ishtaruser.current_profile.auto_pin: + ishtaruser = ( + self.request.user.ishtaruser + if hasattr(self.request.user, "ishtaruser") + else None + ) + if ( + ishtaruser + and ishtaruser.current_profile + and ishtaruser.current_profile.auto_pin + ): self.request.session[self.current_obj_slug] = str(admact.pk) - self.request.session[self.get_object_name(admact)] = str( - admact.pk) + self.request.session[self.get_object_name(admact)] = str(admact.pk) - res = render(self.request, 'ishtar/wizard/wizard_done.html', dct) + res = render(self.request, "ishtar/wizard/wizard_done.html", dct) return res @@ -421,6 +460,7 @@ class OperationEditAdministrativeActWizard(OperationAdministrativeActWizard): def get_associated_item(self, dct): return self.get_current_object().operation + ######## # Site # ######## @@ -439,110 +479,130 @@ class SiteSearch(SiteLabel, SearchWizard): class SiteWizard(SiteLabel, Wizard): - SITE_KEY = 'new' + SITE_KEY = "new" model = models.ArchaeologicalSite - wizard_done_window = reverse_lazy('show-site') + wizard_done_window = reverse_lazy("show-site") redirect_url = "site_modification" class SiteModificationWizard(SiteWizard): - SITE_KEY = 'modification' + SITE_KEY = "modification" modification = True class SiteDeletionWizard(SiteLabel, MultipleDeletionWizard): - SITE_KEY = 'deletion' + SITE_KEY = "deletion" model = models.ArchaeologicalSite - fields = models.ArchaeologicalSite.TABLE_COLS + ['operations'] + fields = models.ArchaeologicalSite.TABLE_COLS + ["operations"] redirect_url = "site_deletion" class AdministrativeActDeletionWizard(ClosingWizard): model = models.AdministrativeAct wizard_templates = { - 'final-operation_administrativeactop_deletion': - 'ishtar/wizard/wizard_adminact_deletion.html', - 'final-file_administrativeactfile_deletion': - 'ishtar/wizard/wizard_adminact_deletion.html'} - fields = ['act_type', 'in_charge', 'operator', 'scientist', 'signatory', - 'operation', 'associated_file', 'signature_date', 'act_object'] - if settings.COUNTRY == 'fr': - fields += ['ref_sra'] + "final-operation_administrativeactop_deletion": "ishtar/wizard/wizard_adminact_deletion.html", + "final-file_administrativeactfile_deletion": "ishtar/wizard/wizard_adminact_deletion.html", + } + fields = [ + "act_type", + "in_charge", + "operator", + "scientist", + "signatory", + "operation", + "associated_file", + "signature_date", + "act_object", + ] + if settings.COUNTRY == "fr": + fields += ["ref_sra"] def done(self, form_list, **kwargs): obj = self.get_current_object() obj.delete() - return render( - self.request, 'ishtar/wizard/wizard_delete_done.html', {}) + return render(self.request, "ishtar/wizard/wizard_delete_done.html", {}) -def is_preventive(form_name, model, type_key='operation_type', key=''): +def is_preventive(form_name, model, type_key="operation_type", key=""): def func(self): request = self.request storage = self.storage - if storage.prefix not in request.session or \ - 'step_data' not in request.session[storage.prefix] or \ - form_name not in request.session[storage.prefix]['step_data'] or\ - form_name + '-' + type_key not in \ - request.session[storage.prefix]['step_data'][form_name]: + if ( + storage.prefix not in request.session + or "step_data" not in request.session[storage.prefix] + or form_name not in request.session[storage.prefix]["step_data"] + or form_name + "-" + type_key + not in request.session[storage.prefix]["step_data"][form_name] + ): return False try: - typ = request.session[storage.prefix][ - 'step_data'][form_name][form_name + '-' + type_key] + typ = request.session[storage.prefix]["step_data"][form_name][ + form_name + "-" + type_key + ] if type(typ) in (list, tuple): typ = typ[0] typ = int(typ) return model.is_preventive(typ, key) except ValueError: return False + return func -def is_not_preventive(form_name, model, type_key='operation_type', key=''): +def is_not_preventive(form_name, model, type_key="operation_type", key=""): def func(self): return not is_preventive(form_name, model, type_key, key)(self) + return func -def is_judiciary(form_name, model, type_key='operation_type'): +def is_judiciary(form_name, model, type_key="operation_type"): def func(self): request = self.request storage = self.storage - if storage.prefix not in request.session or \ - 'step_data' not in request.session[storage.prefix] or \ - form_name not in request.session[storage.prefix]['step_data'] \ - or form_name + '-' + type_key not in \ - request.session[storage.prefix]['step_data'][form_name]: + if ( + storage.prefix not in request.session + or "step_data" not in request.session[storage.prefix] + or form_name not in request.session[storage.prefix]["step_data"] + or form_name + "-" + type_key + not in request.session[storage.prefix]["step_data"][form_name] + ): return False try: - typ = request.session[storage.prefix][ - 'step_data'][form_name][form_name + '-' + type_key] + typ = request.session[storage.prefix]["step_data"][form_name][ + form_name + "-" + type_key + ] if type(typ) in (list, tuple): typ = typ[0] typ = int(typ) return model.is_judiciary(typ) except ValueError: return False + return func -def has_associated_file(form_name, file_key='associated_file', negate=False): +def has_associated_file(form_name, file_key="associated_file", negate=False): def func(self): request = self.request storage = self.storage - if storage.prefix not in request.session or \ - 'step_data' not in request.session[storage.prefix] or \ - form_name not in request.session[storage.prefix]['step_data'] or\ - form_name + '-' + file_key not in \ - request.session[storage.prefix]['step_data'][form_name]: + if ( + storage.prefix not in request.session + or "step_data" not in request.session[storage.prefix] + or form_name not in request.session[storage.prefix]["step_data"] + or form_name + "-" + file_key + not in request.session[storage.prefix]["step_data"][form_name] + ): return negate try: - file_id = request.session[storage.prefix][ - 'step_data'][form_name][form_name + '-' + file_key] + file_id = request.session[storage.prefix]["step_data"][form_name][ + form_name + "-" + file_key + ] if type(file_id) in (list, tuple): file_id = file_id[0] int(file_id) return not negate except ValueError: return negate + return func |