diff options
| -rw-r--r-- | archaeological_files/__init__.py | 2 | ||||
| -rw-r--r-- | archaeological_files/admin.py | 51 | ||||
| -rw-r--r-- | archaeological_files/forms.py | 709 | ||||
| -rw-r--r-- | archaeological_files/ishtar_menu.py | 119 | ||||
| -rw-r--r-- | archaeological_files/lookups.py | 10 | ||||
| -rw-r--r-- | archaeological_files/models.py | 948 | ||||
| -rw-r--r-- | archaeological_files/tests.py | 149 | ||||
| -rw-r--r-- | archaeological_files/urls.py | 175 | ||||
| -rw-r--r-- | archaeological_files/views.py | 347 | ||||
| -rw-r--r-- | archaeological_files/wizards.py | 108 | 
10 files changed, 1519 insertions, 1099 deletions
| diff --git a/archaeological_files/__init__.py b/archaeological_files/__init__.py index c76037d94..0301cf2e3 100644 --- a/archaeological_files/__init__.py +++ b/archaeological_files/__init__.py @@ -1 +1 @@ -default_app_config = 'ishtar_common.apps.ArchaeologicalFilesConfig' +default_app_config = "ishtar_common.apps.ArchaeologicalFilesConfig" diff --git a/archaeological_files/admin.py b/archaeological_files/admin.py index b5709bd65..3c85fcdcd 100644 --- a/archaeological_files/admin.py +++ b/archaeological_files/admin.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -28,31 +28,34 @@ from . import models  class FileAdmin(HistorizedObjectAdmin): -    list_display = ['year', 'numeric_reference', 'file_type', 'name'] -    if settings.COUNTRY == 'fr': -        list_display += ['saisine_type', 'permit_reference'] +    list_display = ["year", "numeric_reference", "file_type", "name"] +    if settings.COUNTRY == "fr": +        list_display += ["saisine_type", "permit_reference"]      list_filter = ["file_type", "year"] -    if settings.COUNTRY == 'fr': -        list_filter += ['saisine_type'] -    search_fields = ('name', 'towns__name', 'permit_reference') +    if settings.COUNTRY == "fr": +        list_filter += ["saisine_type"] +    search_fields = ("name", "towns__name", "permit_reference")      ajax_form_dict = HistorizedObjectAdmin.AJAX_FORM_DICT.copy() -    ajax_form_dict.update({ -        'in_charge': 'person', -        'general_contractor': 'person', -        'corporation_general_contractor': 'organization', -        'responsible_town_planning_service': 'person', -        'planning_service': 'organization', -        'organization': 'organization', -        'scientist': 'person', -        'main_town': 'town', -        'towns': 'town', -        'related_file': 'file' -    }) -    form = make_ajax_form( -        models.File, ajax_form_dict) +    ajax_form_dict.update( +        { +            "in_charge": "person", +            "general_contractor": "person", +            "corporation_general_contractor": "organization", +            "responsible_town_planning_service": "person", +            "planning_service": "organization", +            "organization": "organization", +            "scientist": "person", +            "main_town": "town", +            "towns": "town", +            "related_file": "file", +        } +    ) +    form = make_ajax_form(models.File, ajax_form_dict)      readonly_fields = HistorizedObjectAdmin.readonly_fields + [ -        'raw_general_contractor', 'raw_town_planning_service', -        'cached_label', 'imported_line' +        "raw_general_contractor", +        "raw_town_planning_service", +        "cached_label", +        "imported_line",      ]      exclude = ["documents", "main_image"]      model = models.File @@ -62,7 +65,7 @@ admin_site.register(models.File, FileAdmin)  general_models = [models.FileType, models.PermitType] -if settings.COUNTRY == 'fr': +if settings.COUNTRY == "fr":      general_models.append(models.SaisineType)  for model in general_models:      admin_site.register(model, GeneralTypeAdmin) diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 631407ac0..2cb08b5d7 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.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> @@ -30,22 +30,43 @@ from django.utils.functional import lazy  from django.utils.safestring import mark_safe  from ishtar_common.utils import ugettext_lazy as _ -from ishtar_common.models import Person, Organization, \ -    valid_id, valid_ids, person_type_pks_lazy, \ -    person_type_pk_lazy, organization_type_pks_lazy, \ -    get_sra_agent_head_scientist_label +from ishtar_common.models import ( +    Person, +    Organization, +    valid_id, +    valid_ids, +    person_type_pks_lazy, +    person_type_pk_lazy, +    organization_type_pks_lazy, +    get_sra_agent_head_scientist_label, +)  from ishtar_common.models_common import Department -from archaeological_operations.models import ActType, AdministrativeAct, \ -    OperationType +from archaeological_operations.models import ActType, AdministrativeAct, OperationType  from . import models -from ishtar_common.forms import FinalForm, get_now, reverse_lazy, TableSelect, \ -    ManageOldType, CustomForm, FieldType, IshtarForm, \ -    MultiSearchForm, LockForm, CustomFormSearch, DocumentItemSelect +from ishtar_common.forms import ( +    FinalForm, +    get_now, +    reverse_lazy, +    TableSelect, +    ManageOldType, +    CustomForm, +    FieldType, +    IshtarForm, +    MultiSearchForm, +    LockForm, +    CustomFormSearch, +    DocumentItemSelect, +)  from ishtar_common.forms_common import get_town_field -from archaeological_operations.forms import AdministrativeActForm, \ -    AdministrativeActOpeFormSelection, SLICING, AdministrativeActModifForm, \ -    ParcelForm, ParcelFormSet +from archaeological_operations.forms import ( +    AdministrativeActForm, +    AdministrativeActOpeFormSelection, +    SLICING, +    AdministrativeActModifForm, +    ParcelForm, +    ParcelFormSet, +)  from ishtar_common import widgets  from bootstrap_datepicker.widgets import DatePicker @@ -56,240 +77,274 @@ class FileSelect(DocumentItemSelect):      form_slug = "file-001-search"      search_vector = forms.CharField( -        label=_("Full text search"), widget=widgets.SearchWidget( -            'archaeological-files', 'file' -        )) +        label=_("Full text search"), +        widget=widgets.SearchWidget("archaeological-files", "file"), +    )      year = forms.IntegerField(label=_("Year"))      numeric_reference = forms.IntegerField(label=_("Numeric reference")) -    internal_reference = forms.CharField(max_length=200, -                                         label=_("Other reference")) +    internal_reference = forms.CharField(max_length=200, label=_("Other reference"))      towns = get_town_field()      parcel = forms.CharField(label=_("Parcel"))      if settings.ISHTAR_DPTS:          towns__numero_insee__startswith = forms.ChoiceField( -            label=_("Department"), choices=[]) +            label=_("Department"), choices=[] +        )      name = forms.CharField(label=_("File name"), max_length=200)      file_type = forms.ChoiceField(label=_("File type"), choices=[])      end_date = forms.NullBooleanField(label=_("Is active?"))      saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[])      permit_type = forms.ChoiceField(label=_("Permit type"), choices=[]) -    permit_reference = forms.CharField(max_length=200, -                                       label=_("Permit reference")) +    permit_reference = forms.CharField(max_length=200, label=_("Permit reference"))      comment = forms.CharField(label=_("Comment"), max_length=500)      in_charge = forms.IntegerField(          label=_("In charge"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', -                         args=[person_type_pk_lazy('sra_agent')]), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy( +                "autocomplete-person", args=[person_type_pk_lazy("sra_agent")] +            ), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      general_contractor = forms.IntegerField(          label=_("General contractor"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', -                         args=[person_type_pk_lazy('general_contractor')]), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy( +                "autocomplete-person", args=[person_type_pk_lazy("general_contractor")] +            ), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      general_contractor__attached_to = forms.IntegerField(          label=_("Organization of general contractor"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-organization', -                         args=[organization_type_pks_lazy([ -                             'general_contractor'])]), -            associated_model=Organization), -        validators=[valid_id(Organization)]) +            reverse_lazy( +                "autocomplete-organization", +                args=[organization_type_pks_lazy(["general_contractor"])], +            ), +            associated_model=Organization, +        ), +        validators=[valid_id(Organization)], +    )      history_creator = forms.IntegerField(          label=_("Created by"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', -                         args=['0', 'user']), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy("autocomplete-person", args=["0", "user"]), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      history_modifier = forms.IntegerField(          label=_("Modified by"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', -                         args=['0', 'user']), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy("autocomplete-person", args=["0", "user"]), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      TYPES = [ -        FieldType('saisine_type', models.SaisineType), -        FieldType('permit_type', models.PermitType), -        FieldType('file_type', models.FileType), +        FieldType("saisine_type", models.SaisineType), +        FieldType("permit_type", models.PermitType), +        FieldType("file_type", models.FileType),      ]      def __init__(self, *args, **kwargs):          super(FileSelect, self).__init__(*args, **kwargs) -        k = 'towns__numero_insee__startswith' +        k = "towns__numero_insee__startswith"          if settings.ISHTAR_DPTS and k in self.fields: -            self.fields[k].choices = [ -                ('', '--')] + list(settings.ISHTAR_DPTS) +            self.fields[k].choices = [("", "--")] + list(settings.ISHTAR_DPTS)  class FileFormSelection(LockForm, CustomFormSearch):      SEARCH_AND_SELECT = True      form_label = _("Archaeological file search") -    associated_models = {'pk': models.File} -    currents = {'pk': models.File} +    associated_models = {"pk": models.File} +    currents = {"pk": models.File}      pk = forms.IntegerField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-file'), -            FileSelect, models.File, -            source_full=reverse_lazy('get-file-full')), -        validators=[valid_id(models.File)]) +            reverse_lazy("get-file"), +            FileSelect, +            models.File, +            source_full=reverse_lazy("get-file-full"), +        ), +        validators=[valid_id(models.File)], +    )  class FileFormMultiSelection(LockForm, MultiSearchForm):      form_label = _("Archaeological file search") -    associated_models = {'pks': models.File} +    associated_models = {"pks": models.File}      pk = forms.CharField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-file'), -            FileSelect, models.File, +            reverse_lazy("get-file"), +            FileSelect, +            models.File,              multiple_select=True, -            source_full=reverse_lazy('get-file-full')), -        validators=[valid_ids(models.File)]) +            source_full=reverse_lazy("get-file-full"), +        ), +        validators=[valid_ids(models.File)], +    ) -DATE_SOURCE = (('creation', _("Creation date")), -               ("reception", _("Reception date"))) +DATE_SOURCE = (("creation", _("Creation date")), ("reception", _("Reception date")))  class DashboardForm(IshtarForm): -    slicing = forms.ChoiceField( -        label=_("Slicing"), choices=SLICING, required=False) -    department_detail = forms.BooleanField( -        label=_("Department detail"), required=False) +    slicing = forms.ChoiceField(label=_("Slicing"), choices=SLICING, required=False) +    department_detail = forms.BooleanField(label=_("Department detail"), required=False)      date_source = forms.ChoiceField( -        label=_("Date get from"), choices=DATE_SOURCE, required=False) -    file_type = forms.ChoiceField( -        label=_("File type"), choices=[], required=False) +        label=_("Date get from"), choices=DATE_SOURCE, required=False +    ) +    file_type = forms.ChoiceField(label=_("File type"), choices=[], required=False)      saisine_type = forms.ChoiceField( -        label=_("Saisine type"), choices=[], required=False) -    after = forms.DateField( -        label=_("Date after"), widget=DatePicker, required=False) -    before = forms.DateField( -        label=_("Date before"), widget=DatePicker, required=False) +        label=_("Saisine type"), choices=[], required=False +    ) +    after = forms.DateField(label=_("Date after"), widget=DatePicker, required=False) +    before = forms.DateField(label=_("Date before"), widget=DatePicker, required=False)      def __init__(self, *args, **kwargs): -        if 'prefix' not in kwargs: -            kwargs['prefix'] = 'files' +        if "prefix" not in kwargs: +            kwargs["prefix"] = "files"          super(DashboardForm, self).__init__(*args, **kwargs) -        self.fields['saisine_type'].choices = models.SaisineType.get_types() -        self.fields['file_type'].choices = models.FileType.get_types() +        self.fields["saisine_type"].choices = models.SaisineType.get_types() +        self.fields["file_type"].choices = models.FileType.get_types()      def get_show_detail(self): -        return hasattr(self, 'cleaned_data') and \ -            self.cleaned_data.get('department_detail') +        return hasattr(self, "cleaned_data") and self.cleaned_data.get( +            "department_detail" +        )      def get_date_source(self): -        date_source = 'creation' -        if hasattr(self, 'cleaned_data') and \ -           self.cleaned_data.get('date_source'): -            date_source = self.cleaned_data['date_source'] +        date_source = "creation" +        if hasattr(self, "cleaned_data") and self.cleaned_data.get("date_source"): +            date_source = self.cleaned_data["date_source"]          return date_source      def get_filter(self): -        if not hasattr(self, 'cleaned_data') or not self.cleaned_data: +        if not hasattr(self, "cleaned_data") or not self.cleaned_data:              return {}          date_source = self.get_date_source()          fltr = {} -        if self.cleaned_data.get('saisine_type'): -            fltr['saisine_type_id'] = self.cleaned_data['saisine_type'] -        if self.cleaned_data.get('file_type'): -            fltr['file_type_id'] = self.cleaned_data['file_type'] -        if self.cleaned_data.get('after'): -            fltr[date_source + '_date__gte'] = self.cleaned_data['after'] -        if self.cleaned_data.get('before'): -            fltr[date_source + '_date__lte'] = self.cleaned_data['before'] +        if self.cleaned_data.get("saisine_type"): +            fltr["saisine_type_id"] = self.cleaned_data["saisine_type"] +        if self.cleaned_data.get("file_type"): +            fltr["file_type_id"] = self.cleaned_data["file_type"] +        if self.cleaned_data.get("after"): +            fltr[date_source + "_date__gte"] = self.cleaned_data["after"] +        if self.cleaned_data.get("before"): +            fltr[date_source + "_date__lte"] = self.cleaned_data["before"]          return fltr  class FileFormGeneral(ManageOldType):      form_label = _("General") -    associated_models = {'in_charge': Person, -                         'related_file': models.File, -                         'file_type': models.FileType} +    associated_models = { +        "in_charge": Person, +        "related_file": models.File, +        "file_type": models.FileType, +    }      in_charge = forms.IntegerField(          label=_("Person in charge"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', args=[ -                person_type_pks_lazy(['sra_agent'])]), -            limit={'person_types': [ -                person_type_pk_lazy('sra_agent')]}, -            associated_model=Person, new=True), -        validators=[valid_id(Person)]) -    year = forms.IntegerField(label=_("Year"), -                              initial=lambda: datetime.datetime.now().year, -                              validators=[validators.MinValueValidator(1000), -                                          validators.MaxValueValidator(2100)]) +            reverse_lazy( +                "autocomplete-person", args=[person_type_pks_lazy(["sra_agent"])] +            ), +            limit={"person_types": [person_type_pk_lazy("sra_agent")]}, +            associated_model=Person, +            new=True, +        ), +        validators=[valid_id(Person)], +    ) +    year = forms.IntegerField( +        label=_("Year"), +        initial=lambda: datetime.datetime.now().year, +        validators=[ +            validators.MinValueValidator(1000), +            validators.MaxValueValidator(2100), +        ], +    )      numeric_reference = forms.IntegerField( -        label=_("Numeric reference"), widget=forms.HiddenInput, required=False) +        label=_("Numeric reference"), widget=forms.HiddenInput, required=False +    )      internal_reference = forms.CharField( -        label=_("Other reference"), max_length=60, required=False) +        label=_("Other reference"), max_length=60, required=False +    )      name = forms.CharField(label=_("Name"), required=False, max_length=100) -    creation_date = forms.DateField(label=_("Creation date"), -                                    initial=get_now, widget=DatePicker) +    creation_date = forms.DateField( +        label=_("Creation date"), initial=get_now, widget=DatePicker +    )      file_type = forms.ChoiceField(label=_("File type"), choices=[])      related_file = forms.IntegerField( -        label=_("Related file"), required=False, -        widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'), -                                          associated_model=models.File), -        validators=[valid_id(models.File)]) -    comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, -                              required=False) +        label=_("Related file"), +        required=False, +        widget=widgets.JQueryAutoComplete( +            reverse_lazy("autocomplete-file"), associated_model=models.File +        ), +        validators=[valid_id(models.File)], +    ) +    comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, required=False)      total_surface = forms.FloatField( -        required=False, widget=widgets.AreaWidget, +        required=False, +        widget=widgets.AreaWidget,          label=_("Total surface (m2)"), -        validators=[validators.MinValueValidator(0), -                    validators.MaxValueValidator(999999999)]) +        validators=[ +            validators.MinValueValidator(0), +            validators.MaxValueValidator(999999999), +        ], +    )      address = forms.CharField(label=_("Main address"), widget=forms.Textarea) -    address_complement = forms.CharField(label=_("Main address - complement"), -                                         required=False) +    address_complement = forms.CharField( +        label=_("Main address - complement"), required=False +    )      def __init__(self, *args, **kwargs):          super(FileFormGeneral, self).__init__(*args, **kwargs) -        if 'file_type' in self.fields: -            self.fields['file_type'].choices = models.FileType.get_types( -                initial=self.init_data.get('file_type')) -            self.fields['file_type'].help_text = models.FileType.get_help() -        q = models.File.objects\ -                  .filter(internal_reference__isnull=False)\ -                  .exclude(internal_reference='').order_by('-pk') -        if q.count() and 'internal_reference' in self.fields: -            lbl = self.fields['internal_reference'].label -            lbl += _("<br/>(last recorded: %s)") % ( -                q.all()[0].internal_reference) -            self.fields['internal_reference'].label = mark_safe(lbl) +        if "file_type" in self.fields: +            self.fields["file_type"].choices = models.FileType.get_types( +                initial=self.init_data.get("file_type") +            ) +            self.fields["file_type"].help_text = models.FileType.get_help() +        q = ( +            models.File.objects.filter(internal_reference__isnull=False) +            .exclude(internal_reference="") +            .order_by("-pk") +        ) +        if q.count() and "internal_reference" in self.fields: +            lbl = self.fields["internal_reference"].label +            lbl += _("<br/>(last recorded: %s)") % (q.all()[0].internal_reference) +            self.fields["internal_reference"].label = mark_safe(lbl)  class FileFormGeneralRO(FileFormGeneral):      year = forms.IntegerField( -        label=_("Year"), widget=forms.TextInput(attrs={'readonly': True})) +        label=_("Year"), widget=forms.TextInput(attrs={"readonly": True}) +    )      numeric_reference = forms.IntegerField( -        label=_("Numeric reference"), widget=forms.TextInput()) -    id = forms.IntegerField(' ', widget=forms.HiddenInput, required=False) +        label=_("Numeric reference"), widget=forms.TextInput() +    ) +    id = forms.IntegerField(" ", widget=forms.HiddenInput, required=False)      def clean(self):          cleaned_data = self.cleaned_data -        year = cleaned_data.get('year') -        pk = cleaned_data.get('id') -        numeric_reference = cleaned_data.get('numeric_reference') -        q = models.File.objects\ -                       .filter(year=year, numeric_reference=numeric_reference)\ -                       .exclude(pk=pk) +        year = cleaned_data.get("year") +        pk = cleaned_data.get("id") +        numeric_reference = cleaned_data.get("numeric_reference") +        q = models.File.objects.filter( +            year=year, numeric_reference=numeric_reference +        ).exclude(pk=pk)          if numeric_reference and q.count(): -            raise forms.ValidationError( -                _("Another file with this numeric id exists.")) +            raise forms.ValidationError(_("Another file with this numeric id exists."))          return cleaned_data -ParcelFormset = formset_factory(ParcelForm, can_delete=True, -                                formset=ParcelFormSet) +ParcelFormset = formset_factory(ParcelForm, can_delete=True, formset=ParcelFormSet)  ParcelFormset.form_label = _("Parcels")  ParcelFormset.form_admin_name = _("Archaeological file - 020 - Parcel")  ParcelFormset.form_slug = "file-020-parcels" @@ -297,124 +352,148 @@ ParcelFormset.form_slug = "file-020-parcels"  class FileFormPreventive(ManageOldType, forms.Form):      form_label = _("Preventive informations") -    associated_models = {'general_contractor': Person, -                         'saisine_type': models.SaisineType, -                         'permit_type': models.PermitType, -                         'responsible_town_planning_service': Person} +    associated_models = { +        "general_contractor": Person, +        "saisine_type": models.SaisineType, +        "permit_type": models.PermitType, +        "responsible_town_planning_service": Person, +    }      general_contractor = forms.IntegerField(          label=_("General contractor"),          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-person', -                args=[person_type_pks_lazy(['general_contractor'])] +                "autocomplete-person", +                args=[person_type_pks_lazy(["general_contractor"])],              ), -            limit={'person_types': [ -                person_type_pk_lazy('general_contractor')]}, -            associated_model=Person, new=True), -        validators=[valid_id(Person)]) +            limit={"person_types": [person_type_pk_lazy("general_contractor")]}, +            associated_model=Person, +            new=True, +        ), +        validators=[valid_id(Person)], +    )      responsible_town_planning_service = forms.IntegerField(          required=False,          label=_("Responsible for planning service"),          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-person', -                args=[person_type_pks_lazy(['responsible_planning_service'])] +                "autocomplete-person", +                args=[person_type_pks_lazy(["responsible_planning_service"])],              ), -            limit={'person_types': [ -                    person_type_pk_lazy('responsible_planning_service') -                    ]}, -            associated_model=Person, new=True), -        validators=[valid_id(Person)]) -    permit_type = forms.ChoiceField(label=_("Permit type"), required=False, -                                    choices=[]) +            limit={ +                "person_types": [person_type_pk_lazy("responsible_planning_service")] +            }, +            associated_model=Person, +            new=True, +        ), +        validators=[valid_id(Person)], +    ) +    permit_type = forms.ChoiceField(label=_("Permit type"), required=False, choices=[])      permit_reference = forms.CharField( -        label=_("Permit reference"), required=False, -        validators=[validators.MaxLengthValidator(60)]) +        label=_("Permit reference"), +        required=False, +        validators=[validators.MaxLengthValidator(60)], +    )      total_developed_surface = forms.FloatField( -        widget=widgets.AreaWidget, label=_("Total developed surface (m2)"), -        required=False, validators=[validators.MinValueValidator(0), -                                    validators.MaxValueValidator(999999999)]) -    if settings.COUNTRY == 'fr': -        saisine_type = forms.ChoiceField(label=_("Saisine type"), -                                         choices=[]) +        widget=widgets.AreaWidget, +        label=_("Total developed surface (m2)"), +        required=False, +        validators=[ +            validators.MinValueValidator(0), +            validators.MaxValueValidator(999999999), +        ], +    ) +    if settings.COUNTRY == "fr": +        saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[])      reception_date = forms.DateField( -        label=_("Reception date"), initial=get_now, widget=DatePicker) +        label=_("Reception date"), initial=get_now, widget=DatePicker +    )      def __init__(self, *args, **kwargs):          super(FileFormPreventive, self).__init__(*args, **kwargs) -        if 'saisine_type' in self.fields: -            self.fields['saisine_type'].choices = \ -                models.SaisineType.get_types( -                    initial=self.init_data.get('saisine_type')) -            self.fields['saisine_type'].help_text = \ -                models.SaisineType.get_help() -        if 'permit_type' in self.fields: -            self.fields['permit_type'].choices = models.PermitType.get_types( -                initial=self.init_data.get('permit_type'), default='NP') -            self.fields['permit_type'].help_text = models.PermitType.get_help() +        if "saisine_type" in self.fields: +            self.fields["saisine_type"].choices = models.SaisineType.get_types( +                initial=self.init_data.get("saisine_type") +            ) +            self.fields["saisine_type"].help_text = models.SaisineType.get_help() +        if "permit_type" in self.fields: +            self.fields["permit_type"].choices = models.PermitType.get_types( +                initial=self.init_data.get("permit_type"), default="NP" +            ) +            self.fields["permit_type"].help_text = models.PermitType.get_help()  class FileFormResearch(CustomForm, ManageOldType, forms.Form):      form_label = _("Research archaeology")      form_admin_name = _("Archaeological file - 045 - Research - General")      form_slug = "file-045-research-general" -    base_model = 'department' -    associated_models = {'scientist': Person, -                         'requested_operation_type': OperationType, -                         'organization': Organization, -                         'department': Department} +    base_model = "department" +    associated_models = { +        "scientist": Person, +        "requested_operation_type": OperationType, +        "organization": Organization, +        "department": Department, +    }      department = widgets.Select2MultipleField( -        model=Department, label=_("Departments"), required=False) +        model=Department, label=_("Departments"), required=False +    )      scientist = forms.IntegerField(          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-person', -                args=[person_type_pks_lazy(['head_scientist', 'sra_agent'])] +                "autocomplete-person", +                args=[person_type_pks_lazy(["head_scientist", "sra_agent"])],              ), -            limit={'person_types': [person_type_pk_lazy('head_scientist'), -                                    person_type_pk_lazy('sra_agent')]}, +            limit={ +                "person_types": [ +                    person_type_pk_lazy("head_scientist"), +                    person_type_pk_lazy("sra_agent"), +                ] +            },              tips=lazy(get_sra_agent_head_scientist_label), -            associated_model=Person, new=True, +            associated_model=Person, +            new=True,              detail=True, -            modify=True +            modify=True,          ), -        label=_("Scientist in charge")) +        label=_("Scientist in charge"), +    )      requested_operation_type = forms.ChoiceField( -        label=_("Requested operation type"), choices=[]) +        label=_("Requested operation type"), choices=[] +    )      organization = forms.IntegerField(          label=_("Lead organization"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-organization'), -            associated_model=Organization, new=True, +            reverse_lazy("autocomplete-organization"), +            associated_model=Organization, +            new=True,              detail=True, -            modify=True +            modify=True,          ), -        validators=[valid_id(Organization)], required=False, +        validators=[valid_id(Organization)], +        required=False,      ) -    if settings.COUNTRY == 'fr': -        cira_advised = forms.NullBooleanField(label="Passage en CIRA", -                                              required=False) +    if settings.COUNTRY == "fr": +        cira_advised = forms.NullBooleanField(label="Passage en CIRA", required=False)      research_comment = forms.CharField( -        label=_("Comment"), widget=forms.Textarea, required=False) -    if settings.COUNTRY == 'fr': +        label=_("Comment"), widget=forms.Textarea, required=False +    ) +    if settings.COUNTRY == "fr":          mh_register = forms.NullBooleanField( -            label="Sur Monument Historique classé", required=False) +            label="Sur Monument Historique classé", required=False +        )          mh_listing = forms.NullBooleanField( -            label="Sur Monument Historique inscrit", required=False) -    classified_area = forms.NullBooleanField( -        label=_("Classified area"), required=False) -    protected_area = forms.NullBooleanField( -        label=_("Protected area"), required=False) +            label="Sur Monument Historique inscrit", required=False +        ) +    classified_area = forms.NullBooleanField(label=_("Classified area"), required=False) +    protected_area = forms.NullBooleanField(label=_("Protected area"), required=False)      def __init__(self, *args, **kwargs):          super(FileFormResearch, self).__init__(*args, **kwargs) -        if 'requested_operation_type' in self.fields: -            self.fields['requested_operation_type'].choices = \ -                OperationType.get_types( -                    dct={"preventive": False}, -                    initial=self.init_data.get('requested_operation_type')) -            self.fields['requested_operation_type'].help_text = \ -                OperationType.get_help() +        if "requested_operation_type" in self.fields: +            self.fields["requested_operation_type"].choices = OperationType.get_types( +                dct={"preventive": False}, +                initial=self.init_data.get("requested_operation_type"), +            ) +            self.fields["requested_operation_type"].help_text = OperationType.get_help()  class FinalFileClosingForm(FinalForm): @@ -431,147 +510,171 @@ class AdministrativeActFileModifySelect(TableSelect):      _model = AdministrativeAct      search_vector = forms.CharField( -        label=_("Full text search"), widget=widgets.SearchWidget( -            'archaeological-operations', 'administrativeact', -            'administrativeactfile', -        )) +        label=_("Full text search"), +        widget=widgets.SearchWidget( +            "archaeological-operations", +            "administrativeact", +            "administrativeactfile", +        ), +    )      year = forms.IntegerField(label=_("Year"))      index = forms.IntegerField(label=_("Index")) -    if settings.COUNTRY == 'fr': -        ref_sra = forms.CharField(label="Référence SRA", -                                  max_length=15) +    if settings.COUNTRY == "fr": +        ref_sra = forms.CharField(label="Référence SRA", max_length=15)      act_type = forms.ChoiceField(label=_("Act type"), choices=[]) -    act_object = forms.CharField(label=_("Object (full text search)"), -                                 max_length=300) +    act_object = forms.CharField(label=_("Object (full text search)"), max_length=300)      operation__towns = get_town_field()      if settings.ISHTAR_DPTS:          operation__towns__numero_insee__startswith = forms.ChoiceField( -            label=_("Department"), choices=[]) +            label=_("Department"), choices=[] +        )      def __init__(self, *args, **kwargs): -        super(AdministrativeActFileModifySelect, self).__init__(*args, -                                                                **kwargs) -        if 'act_type' in self.fields: -            self.fields['act_type'].choices = ActType.get_types( -                dct={'intented_to': 'F'}) -            self.fields['act_type'].help_text = ActType.get_help( -                dct={'intented_to': 'F'}) -        k = 'operation__towns__numero_insee__startswith' +        super(AdministrativeActFileModifySelect, self).__init__(*args, **kwargs) +        if "act_type" in self.fields: +            self.fields["act_type"].choices = ActType.get_types( +                dct={"intented_to": "F"} +            ) +            self.fields["act_type"].help_text = ActType.get_help( +                dct={"intented_to": "F"} +            ) +        k = "operation__towns__numero_insee__startswith"          if settings.ISHTAR_DPTS and k in self.fields: -            self.fields[k].choices = [ -                ('', '--')] + list(settings.ISHTAR_DPTS) +            self.fields[k].choices = [("", "--")] + list(settings.ISHTAR_DPTS)  class AdministrativeActFileSelect(TableSelect):      _model = AdministrativeAct      search_vector = forms.CharField( -        label=_("Full text search"), widget=widgets.SearchWidget( -            'archaeological-operations', 'administrativeact', -            'administrativeactfile', -        )) +        label=_("Full text search"), +        widget=widgets.SearchWidget( +            "archaeological-operations", +            "administrativeact", +            "administrativeactfile", +        ), +    )      year = forms.IntegerField(label=_("Year"))      index = forms.IntegerField(label=_("Index")) -    if settings.COUNTRY == 'fr': -        ref_sra = forms.CharField(label="Autre référence", -                                  max_length=15) +    if settings.COUNTRY == "fr": +        ref_sra = forms.CharField(label="Autre référence", max_length=15)      act_type = forms.ChoiceField(label=_("Act type"), choices=[])      indexed = forms.NullBooleanField(label=_("Indexed?"))      associated_file__towns = get_town_field()      parcel = forms.CharField(label=_("Parcel"))      if settings.ISHTAR_DPTS:          associated_file__towns__numero_insee__startswith = forms.ChoiceField( -            label=_("Department"), choices=[]) -    act_object = forms.CharField(label=_("Object"), -                                 max_length=300) +            label=_("Department"), choices=[] +        ) +    act_object = forms.CharField(label=_("Object"), max_length=300)      signature_date_before = forms.DateField( -        label=_("Signature date before"), widget=DatePicker) +        label=_("Signature date before"), widget=DatePicker +    )      signature_date_after = forms.DateField( -        label=_("Signature date after"), widget=DatePicker) -    associated_file__name = forms.CharField( -        label=_("File name"), max_length=200) +        label=_("Signature date after"), widget=DatePicker +    ) +    associated_file__name = forms.CharField(label=_("File name"), max_length=200)      associated_file__general_contractor = forms.IntegerField(          label=_("General contractor"),          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-person', -                args=[person_type_pk_lazy('general_contractor')]), -                associated_model=Person), -        validators=[valid_id(Person)]) +                "autocomplete-person", args=[person_type_pk_lazy("general_contractor")] +            ), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      associated_file__general_contractor__attached_to = forms.IntegerField(          label=_("Organization of general contractor"),          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-organization', -                args=[organization_type_pks_lazy(['general_contractor'])]), -            associated_model=Organization), -        validators=[valid_id(Organization)]) +                "autocomplete-organization", +                args=[organization_type_pks_lazy(["general_contractor"])], +            ), +            associated_model=Organization, +        ), +        validators=[valid_id(Organization)], +    )      associated_file__numeric_reference = forms.IntegerField( -        label=_("File numeric reference")) +        label=_("File numeric reference") +    )      associated_file__year = forms.IntegerField(label=_("File year"))      associated_file__internal_reference = forms.CharField( -        max_length=200, label=_("File other reference")) +        max_length=200, label=_("File other reference") +    )      associated_file__in_charge = forms.IntegerField(          label=_("File in charge"),          widget=widgets.JQueryAutoComplete(              reverse_lazy( -                'autocomplete-person', -                args=[person_type_pk_lazy('sra_agent')]), -            associated_model=Person), -        validators=[valid_id(Person)]) +                "autocomplete-person", args=[person_type_pk_lazy("sra_agent")] +            ), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      associated_file__permit_reference = forms.CharField( -        max_length=200, label=_("File permit reference")) +        max_length=200, label=_("File permit reference") +    )      history_creator = forms.IntegerField(          label=_("Created by"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy( -                'autocomplete-person', -                args=['0', 'user']), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy("autocomplete-person", args=["0", "user"]), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      history_modifier = forms.IntegerField(          label=_("Modified by"),          widget=widgets.JQueryAutoComplete( -            reverse_lazy('autocomplete-person', -                         args=['0', 'user']), -            associated_model=Person), -        validators=[valid_id(Person)]) +            reverse_lazy("autocomplete-person", args=["0", "user"]), +            associated_model=Person, +        ), +        validators=[valid_id(Person)], +    )      def __init__(self, *args, **kwargs):          super(AdministrativeActFileSelect, self).__init__(*args, **kwargs) -        if 'act_type' in self.fields: -            self.fields['act_type'].choices = ActType.get_types( -                dct={'intented_to': 'F'}) -            self.fields['act_type'].help_text = ActType.get_help( -                dct={'intented_to': 'F'}) -        k = 'associated_file__towns__numero_insee__startswith' +        if "act_type" in self.fields: +            self.fields["act_type"].choices = ActType.get_types( +                dct={"intented_to": "F"} +            ) +            self.fields["act_type"].help_text = ActType.get_help( +                dct={"intented_to": "F"} +            ) +        k = "associated_file__towns__numero_insee__startswith"          if k in self.fields and settings.ISHTAR_DPTS: -            self.fields[k].choices = [ -                ('', '--')] + list(settings.ISHTAR_DPTS) +            self.fields[k].choices = [("", "--")] + list(settings.ISHTAR_DPTS)  class AdministrativeActFileFormSelection(AdministrativeActOpeFormSelection):      SEARCH_AND_SELECT = True      pk = forms.IntegerField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-administrativeactfile'), -            AdministrativeActFileSelect, AdministrativeAct, -            table_cols='TABLE_COLS_FILE'), -        validators=[valid_id(AdministrativeAct)]) +            reverse_lazy("get-administrativeactfile"), +            AdministrativeActFileSelect, +            AdministrativeAct, +            table_cols="TABLE_COLS_FILE", +        ), +        validators=[valid_id(AdministrativeAct)], +    ) -class AdministrativeActFileModifyFormSelection( -        AdministrativeActOpeFormSelection): +class AdministrativeActFileModifyFormSelection(AdministrativeActOpeFormSelection):      SEARCH_AND_SELECT = True      pk = forms.IntegerField( -        label="", required=False, +        label="", +        required=False,          widget=widgets.DataTable( -            reverse_lazy('get-administrativeactfile'), -            AdministrativeActFileModifySelect, AdministrativeAct, -            table_cols='TABLE_COLS_FILE'), -        validators=[valid_id(AdministrativeAct)]) +            reverse_lazy("get-administrativeactfile"), +            AdministrativeActFileModifySelect, +            AdministrativeAct, +            table_cols="TABLE_COLS_FILE", +        ), +        validators=[valid_id(AdministrativeAct)], +    )  class AdministrativeActFileForm(AdministrativeActForm): @@ -580,12 +683,12 @@ class AdministrativeActFileForm(AdministrativeActForm):      act_type = forms.ChoiceField(label=_("Act type"), choices=[])      TYPES = [ -        FieldType('act_type', ActType, -                  extra_args={"dct": {'intented_to': 'F'}}), +        FieldType("act_type", ActType, extra_args={"dct": {"intented_to": "F"}}),      ] -class AdministrativeActFileModifForm(AdministrativeActModifForm, -                                     AdministrativeActFileForm): +class AdministrativeActFileModifForm( +    AdministrativeActModifForm, AdministrativeActFileForm +):      pk = forms.IntegerField(required=False, widget=forms.HiddenInput)      index = forms.IntegerField(label=_("Index"), required=False) diff --git a/archaeological_files/ishtar_menu.py b/archaeological_files/ishtar_menu.py index 7c5f870a6..3d6b85466 100644 --- a/archaeological_files/ishtar_menu.py +++ b/archaeological_files/ishtar_menu.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2010-2016 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -28,52 +28,77 @@ from . import models  # be carreful: each access_controls must be relevant with check_rights in urls  MENU_SECTIONS = [ -    (20, -     SectionItem( -         'file_management', _("Archaeological file"), -         profile_restriction='files', -         css='menu-file', -         childs=[ -             MenuItem( -                 'file_search', _("Search"), -                 model=models.File, -                 access_controls=['view_file', 'view_own_file']), -             MenuItem( -                 'file_creation', _("Creation"), -                 model=models.File, -                 access_controls=['add_file', 'add_own_file']), -             MenuItem( -                 'file_modification', _("Modification"), -                 model=models.File, -                 access_controls=['change_file', 'change_own_file']), -             MenuItem( -                 'file_closing', _("Closing"), -                 model=models.File, -                 access_controls=['close_file']), -             MenuItem( -                 'file_deletion', _("Deletion"), -                 model=models.File, -                 access_controls=['delete_file', 'delete_own_file']), -             SectionItem( -                 'admin_act_files', _("Administrative act"), -                 childs=[ -                     MenuItem('file_administrativeactfil_search', -                              _("Search"), -                              model=AdministrativeAct, -                              access_controls=['change_administrativeact']), -                     MenuItem('file_administrativeactfil', -                              _("Creation"), -                              model=AdministrativeAct, -                              access_controls=['change_administrativeact']), -                     MenuItem('file_administrativeactfil_modification', -                              _("Modification"), -                              model=AdministrativeAct, -                              access_controls=['change_administrativeact']), -                     MenuItem('file_administrativeactfil_deletion', -                              _("Deletion"), -                              model=AdministrativeAct, -                              access_controls=['change_administrativeact']), -                 ],)]),), +    ( +        20, +        SectionItem( +            "file_management", +            _("Archaeological file"), +            profile_restriction="files", +            css="menu-file", +            childs=[ +                MenuItem( +                    "file_search", +                    _("Search"), +                    model=models.File, +                    access_controls=["view_file", "view_own_file"], +                ), +                MenuItem( +                    "file_creation", +                    _("Creation"), +                    model=models.File, +                    access_controls=["add_file", "add_own_file"], +                ), +                MenuItem( +                    "file_modification", +                    _("Modification"), +                    model=models.File, +                    access_controls=["change_file", "change_own_file"], +                ), +                MenuItem( +                    "file_closing", +                    _("Closing"), +                    model=models.File, +                    access_controls=["close_file"], +                ), +                MenuItem( +                    "file_deletion", +                    _("Deletion"), +                    model=models.File, +                    access_controls=["delete_file", "delete_own_file"], +                ), +                SectionItem( +                    "admin_act_files", +                    _("Administrative act"), +                    childs=[ +                        MenuItem( +                            "file_administrativeactfil_search", +                            _("Search"), +                            model=AdministrativeAct, +                            access_controls=["change_administrativeact"], +                        ), +                        MenuItem( +                            "file_administrativeactfil", +                            _("Creation"), +                            model=AdministrativeAct, +                            access_controls=["change_administrativeact"], +                        ), +                        MenuItem( +                            "file_administrativeactfil_modification", +                            _("Modification"), +                            model=AdministrativeAct, +                            access_controls=["change_administrativeact"], +                        ), +                        MenuItem( +                            "file_administrativeactfil_deletion", +                            _("Deletion"), +                            model=AdministrativeAct, +                            access_controls=["change_administrativeact"], +                        ), +                    ], +                ), +            ], +        ), +    ),  ]  """      (100, diff --git a/archaeological_files/lookups.py b/archaeological_files/lookups.py index a96974c9f..cd5d0f0d7 100644 --- a/archaeological_files/lookups.py +++ b/archaeological_files/lookups.py @@ -6,18 +6,16 @@ from django.db.models import Q  from archaeological_files.models import File -@register('file') +@register("file")  class FileLookup(LookupChannel):      model = File      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 diff --git a/archaeological_files/models.py b/archaeological_files/models.py index b897911eb..88326d405 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2012-2017 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -30,30 +30,53 @@ from django.db.models.signals import post_save, m2m_changed, post_delete  from django.core.urlresolvers import reverse  from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy -from ishtar_common.utils import cached_label_changed, get_cache, \ -    get_current_year, m2m_historization_changed - -from ishtar_common.models import GeneralType, BaseHistorizedItem, \ -    OwnPerms, Person, Organization, Town, \ -    Dashboard, DashboardFormItem, ValueGetter, ShortMenuItem, \ -    OperationType, get_generated_id, post_save_cache, Document, HistoryModel, \ -    SearchAltName, SearchVectorConfig, DocumentItem, CompleteIdentifierItem +from ishtar_common.utils import ( +    cached_label_changed, +    get_cache, +    get_current_year, +    m2m_historization_changed, +) + +from ishtar_common.models import ( +    GeneralType, +    BaseHistorizedItem, +    OwnPerms, +    Person, +    Organization, +    Town, +    Dashboard, +    DashboardFormItem, +    ValueGetter, +    ShortMenuItem, +    OperationType, +    get_generated_id, +    post_save_cache, +    Document, +    HistoryModel, +    SearchAltName, +    SearchVectorConfig, +    DocumentItem, +    CompleteIdentifierItem, +)  from ishtar_common.models_common import HistoricalRecords, Department -from archaeological_operations.models import get_values_town_related, \ -    ClosedItem, ParcelItem +from archaeological_operations.models import ( +    get_values_town_related, +    ClosedItem, +    ParcelItem, +)  class FileType(GeneralType):      class Meta:          verbose_name = _("Archaeological file type")          verbose_name_plural = _("Archaeological file types") -        ordering = ('label',) +        ordering = ("label",)      @classmethod -    def is_preventive(cls, file_type_id, key=''): -        key = key or 'preventive' +    def is_preventive(cls, file_type_id, key=""): +        key = key or "preventive"          try:              preventive = FileType.get_cache(key).pk              return file_type_id == preventive @@ -69,314 +92,375 @@ class PermitType(GeneralType):      class Meta:          verbose_name = _("Permit type")          verbose_name_plural = _("Permit types") -        ordering = ('label',) +        ordering = ("label",)  post_save.connect(post_save_cache, sender=PermitType)  post_delete.connect(post_save_cache, sender=PermitType) -if settings.COUNTRY == 'fr': +if settings.COUNTRY == "fr": +      class SaisineType(GeneralType, ValueGetter):          delay = models.IntegerField(_("Delay (in days)"), default=30)          class Meta:              verbose_name = "Type de saisine"              verbose_name_plural = "Types de saisine" -            ordering = ('label',) +            ordering = ("label",) +      post_save.connect(post_save_cache, sender=SaisineType)      post_delete.connect(post_save_cache, sender=SaisineType) -class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem, -           OwnPerms, ValueGetter, ShortMenuItem, DashboardFormItem, ParcelItem): -    SLUG = 'file' -    SHOW_URL = 'show-file' -    DELETE_URL = 'delete-file' +class File( +    ClosedItem, +    DocumentItem, +    BaseHistorizedItem, +    CompleteIdentifierItem, +    OwnPerms, +    ValueGetter, +    ShortMenuItem, +    DashboardFormItem, +    ParcelItem, +): +    SLUG = "file" +    SHOW_URL = "show-file" +    DELETE_URL = "delete-file"      APP = "archaeological-files"      MODEL = "file" -    TABLE_COLS = ['numeric_reference', 'year', 'internal_reference', -                  'file_type', 'saisine_type', 'towns_label', ] +    TABLE_COLS = [ +        "numeric_reference", +        "year", +        "internal_reference", +        "file_type", +        "saisine_type", +        "towns_label", +    ]      # statistics -    STATISTIC_MODALITIES_OPTIONS = OrderedDict([ -        ('year', _("Year")), -        ("file_type__label",  _("File type")), -        ("towns__areas__label", _("Area")), -        ("towns__areas__parent__label", _("Extended area")), -        ("saisine_type__label", "Type de saisine"), -        ("permit_type__label", _("Permit type")), -        ("requested_operation_type__label",  _("File type")), -    ]) -    STATISTIC_MODALITIES = [ -        key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()] +    STATISTIC_MODALITIES_OPTIONS = OrderedDict( +        [ +            ("year", _("Year")), +            ("file_type__label", _("File type")), +            ("towns__areas__label", _("Area")), +            ("towns__areas__parent__label", _("Extended area")), +            ("saisine_type__label", "Type de saisine"), +            ("permit_type__label", _("Permit type")), +            ("requested_operation_type__label", _("File type")), +        ] +    ) +    STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]      STATISTIC_SUM_VARIABLE = OrderedDict(          (              ("pk", (_("Number"), 1)),              ("total_surface", (_("Total surface (km2)"), 0.000001)), -            ("total_developed_surface", ( -                _("Total developed surface (km2)"), 0.000001)), +            ("total_developed_surface", (_("Total developed surface (km2)"), 0.000001)),          )      )      # search parameters -    BOOL_FIELDS = ['end_date__isnull'] +    BOOL_FIELDS = ["end_date__isnull"]      EXTRA_REQUEST_KEYS = { -        'parcel_0': ('parcels__section', -                     'operations__parcels__section'), -        'parcel_1': ('parcels__parcel_number', -                     'operations__parcels__parcel_number'), -        'parcel_2': ('operations__parcels__public_domain', -                     'parcels__public_domain'), -        'end_date': 'end_date__isnull', -        'towns__numero_insee__startswith': -        'towns__numero_insee__startswith', -        'name': 'name__icontains', -        'cached_label': 'cached_label__icontains', -        'comment': 'comment__icontains', -        'permit_reference': 'permit_reference__icontains', -        'general_contractor__attached_to': -            'general_contractor__attached_to__pk', -        'history_creator': 'history_creator__ishtaruser__person__pk', -        'history_modifier': 'history_modifier__ishtaruser__person__pk', -        'towns_label': 'towns', -        'general_contractor__pk': 'general_contractor__pk', -        'responsible_town_planning_service__pk': -            'responsible_town_planning_service__pk', -        'in_charge__pk': 'in_charge__pk', +        "parcel_0": ("parcels__section", "operations__parcels__section"), +        "parcel_1": ("parcels__parcel_number", "operations__parcels__parcel_number"), +        "parcel_2": ("operations__parcels__public_domain", "parcels__public_domain"), +        "end_date": "end_date__isnull", +        "towns__numero_insee__startswith": "towns__numero_insee__startswith", +        "name": "name__icontains", +        "cached_label": "cached_label__icontains", +        "comment": "comment__icontains", +        "permit_reference": "permit_reference__icontains", +        "general_contractor__attached_to": "general_contractor__attached_to__pk", +        "history_creator": "history_creator__ishtaruser__person__pk", +        "history_modifier": "history_modifier__ishtaruser__person__pk", +        "towns_label": "towns", +        "general_contractor__pk": "general_contractor__pk", +        "responsible_town_planning_service__pk": "responsible_town_planning_service__pk", +        "in_charge__pk": "in_charge__pk",      }      BASE_SEARCH_VECTORS = [ -        SearchVectorConfig('name'), -        SearchVectorConfig('internal_reference'), -        SearchVectorConfig('file_type__label'), -        SearchVectorConfig('saisine_type__label'), -        SearchVectorConfig('permit_type__label'), -        SearchVectorConfig('permit_reference'), -        SearchVectorConfig('comment', 'local'), -        SearchVectorConfig('research_comment', 'local') +        SearchVectorConfig("name"), +        SearchVectorConfig("internal_reference"), +        SearchVectorConfig("file_type__label"), +        SearchVectorConfig("saisine_type__label"), +        SearchVectorConfig("permit_type__label"), +        SearchVectorConfig("permit_reference"), +        SearchVectorConfig("comment", "local"), +        SearchVectorConfig("research_comment", "local"),      ] -    INT_SEARCH_VECTORS = [SearchVectorConfig('numeric_reference'), -                          SearchVectorConfig('year')] -    M2M_SEARCH_VECTORS = [SearchVectorConfig('towns__name')] +    INT_SEARCH_VECTORS = [ +        SearchVectorConfig("numeric_reference"), +        SearchVectorConfig("year"), +    ] +    M2M_SEARCH_VECTORS = [SearchVectorConfig("towns__name")]      PARENT_SEARCH_VECTORS = [ -        'in_charge', 'general_contractor', 'corporation_general_contractor', -        'responsible_town_planning_service', 'planning_service', 'organization', -        'scientist' +        "in_charge", +        "general_contractor", +        "corporation_general_contractor", +        "responsible_town_planning_service", +        "planning_service", +        "organization", +        "scientist",      ]      COL_LABELS = { -        'towns_label': _("Towns"), +        "towns_label": _("Towns"),      }      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",      ]      # alternative names of fields for searches      ALT_NAMES = { -        'year': SearchAltName( -            pgettext_lazy("key for text search", "year"), -            'year' -        ), -        'numeric_reference': SearchAltName( -            pgettext_lazy("key for text search", "reference"), -            'numeric_reference' +        "year": SearchAltName(pgettext_lazy("key for text search", "year"), "year"), +        "numeric_reference": SearchAltName( +            pgettext_lazy("key for text search", "reference"), "numeric_reference"          ), -        'internal_reference': SearchAltName( +        "internal_reference": SearchAltName(              pgettext_lazy("key for text search", "other-reference"), -            'internal_reference__iexact' +            "internal_reference__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"          ), -        '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",          ), -        'name': SearchAltName( -            pgettext_lazy("key for text search", "name"), -            'name__iexact' +        "name": SearchAltName( +            pgettext_lazy("key for text search", "name"), "name__iexact"          ), -        'file_type': SearchAltName( -            pgettext_lazy("key for text search", "type"), -            'file_type__label__iexact' +        "file_type": SearchAltName( +            pgettext_lazy("key for text search", "type"), "file_type__label__iexact"          ), -        'end_date': SearchAltName( -            pgettext_lazy("key for text search", "active"), -            'end_date__isnull' +        "end_date": SearchAltName( +            pgettext_lazy("key for text search", "active"), "end_date__isnull"          ), -        'saisine_type': SearchAltName( +        "saisine_type": SearchAltName(              pgettext_lazy("key for text search", "saisine-type"), -            'saisine_type__label__iexact' +            "saisine_type__label__iexact",          ), -        'permit_type': SearchAltName( +        "permit_type": SearchAltName(              pgettext_lazy("key for text search", "permit-type"), -            'permit_type__label__iexact' +            "permit_type__label__iexact",          ), -        'permit_reference': SearchAltName( +        "permit_reference": SearchAltName(              pgettext_lazy("key for text search", "permit-reference"), -            'permit_reference__iexact' +            "permit_reference__iexact",          ), -        'comment': SearchAltName( -            pgettext_lazy("key for text search", "comment"), -            'comment__iexact' +        "comment": SearchAltName( +            pgettext_lazy("key for text search", "comment"), "comment__iexact"          ), -        'in_charge': SearchAltName( +        "in_charge": SearchAltName(              pgettext_lazy("key for text search", "in-charge"), -            'in_charge__cached_label__iexact' +            "in_charge__cached_label__iexact",          ), -        'general_contractor': SearchAltName( +        "general_contractor": SearchAltName(              pgettext_lazy("key for text search", "general-contractor"), -            'general_contractor__cached_label__iexact' +            "general_contractor__cached_label__iexact",          ), -        'general_contractor__attached_to': SearchAltName( -            pgettext_lazy("key for text search", -                          "general-contractor-organization"), -            'general_contractor__attached_to__cached_label__iexact' +        "general_contractor__attached_to": SearchAltName( +            pgettext_lazy("key for text search", "general-contractor-organization"), +            "general_contractor__attached_to__cached_label__iexact",          ),      }      ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)      ALT_NAMES.update(DocumentItem.ALT_NAMES)      POST_PROCESS_REQUEST = { -        'towns__numero_insee__startswith': '_get_department_code', +        "towns__numero_insee__startswith": "_get_department_code",      } -    HISTORICAL_M2M = ['towns', 'departments'] +    HISTORICAL_M2M = ["towns", "departments"]      # fields      year = models.IntegerField(_("Year"), default=get_current_year)      numeric_reference = models.IntegerField( -        _("Numeric reference"), blank=True, null=True) -    internal_reference = models.CharField(_("Internal reference"), blank=True, -                                          null=True, max_length=60) -    external_id = models.CharField(_("External ID"), blank=True, null=True, -                                   max_length=120) +        _("Numeric reference"), blank=True, null=True +    ) +    internal_reference = models.CharField( +        _("Internal reference"), blank=True, null=True, max_length=60 +    ) +    external_id = models.CharField( +        _("External ID"), blank=True, null=True, max_length=120 +    )      auto_external_id = models.BooleanField( -        _("External ID is set automatically"), default=False) +        _("External ID is set automatically"), default=False +    )      name = models.TextField(_("Name"), blank=True, default="")      file_type = models.ForeignKey(FileType, verbose_name=_("File type")) -    in_charge = models.ForeignKey(Person, related_name='file_responsability', -                                  verbose_name=_("Person in charge"), -                                  on_delete=models.SET_NULL, -                                  blank=True, null=True) +    in_charge = models.ForeignKey( +        Person, +        related_name="file_responsability", +        verbose_name=_("Person in charge"), +        on_delete=models.SET_NULL, +        blank=True, +        null=True, +    )      general_contractor = models.ForeignKey( -        Person, related_name='general_contractor_files', -        verbose_name=_("General contractor"), blank=True, null=True, -        on_delete=models.SET_NULL,)  # aménageur - personne -    raw_general_contractor = models.CharField(_("General contractor (raw)"), -                                              max_length=200, blank=True, null=True) +        Person, +        related_name="general_contractor_files", +        verbose_name=_("General contractor"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL, +    )  # aménageur - personne +    raw_general_contractor = models.CharField( +        _("General contractor (raw)"), max_length=200, blank=True, null=True +    )      corporation_general_contractor = models.ForeignKey(          Organization, -        related_name='general_contractor_files', -        verbose_name=_("General contractor organization"), blank=True, -        null=True, on_delete=models.SET_NULL,)  # aménageur +        related_name="general_contractor_files", +        verbose_name=_("General contractor organization"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL, +    )  # aménageur      responsible_town_planning_service = models.ForeignKey( -        Person, related_name='responsible_town_planning_service_files', -        blank=True, null=True, +        Person, +        related_name="responsible_town_planning_service_files", +        blank=True, +        null=True,          verbose_name=_("Responsible for planning service"), -        on_delete=models.SET_NULL,)  # service instructeur - personne +        on_delete=models.SET_NULL, +    )  # service instructeur - personne      raw_town_planning_service = models.CharField( -        _("Planning service (raw)"), max_length=200, -        blank=True, null=True) +        _("Planning service (raw)"), max_length=200, blank=True, null=True +    )      planning_service = models.ForeignKey(          Organization, -        related_name='planning_service_files', -        blank=True, null=True, +        related_name="planning_service_files", +        blank=True, +        null=True,          verbose_name=_("Planning service organization"), -        on_delete=models.SET_NULL,)  # service instructeur +        on_delete=models.SET_NULL, +    )  # service instructeur      permit_type = models.ForeignKey( -        PermitType, verbose_name=_("Permit type"), blank=True, null=True, -        on_delete=models.SET_NULL +        PermitType, +        verbose_name=_("Permit type"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL,      ) -    permit_reference = models.TextField( -        _("Permit reference"), blank=True, default="") +    permit_reference = models.TextField(_("Permit reference"), blank=True, default="")      end_date = models.DateField(_("Closing date"), null=True, blank=True)      main_town = models.ForeignKey( -        Town, verbose_name=_("Main town"), null=True, blank=True, -        related_name='file_main', -        on_delete=models.SET_NULL +        Town, +        verbose_name=_("Main town"), +        null=True, +        blank=True, +        related_name="file_main", +        on_delete=models.SET_NULL, +    ) +    towns = models.ManyToManyField( +        Town, verbose_name=_("Towns"), related_name="file", blank=True      ) -    towns = models.ManyToManyField(Town, verbose_name=_("Towns"), -                                   related_name='file', blank=True)      creation_date = models.DateField( -        _("Creation date"), default=datetime.date.today, blank=True, -        null=True) -    reception_date = models.DateField(_('Reception date'), blank=True, -                                      null=True) +        _("Creation date"), default=datetime.date.today, blank=True, null=True +    ) +    reception_date = models.DateField(_("Reception date"), blank=True, null=True)      planning_service_date = models.DateField( -        _("Date of planning service file"), null=True, blank=True) +        _("Date of planning service file"), null=True, blank=True +    )      related_file = models.ForeignKey( -        "File", verbose_name=_("Related file"), blank=True, null=True, -        on_delete=models.SET_NULL +        "File", +        verbose_name=_("Related file"), +        blank=True, +        null=True, +        on_delete=models.SET_NULL,      ) -    if settings.COUNTRY == 'fr': +    if settings.COUNTRY == "fr":          saisine_type = models.ForeignKey( -            SaisineType, blank=True, null=True, +            SaisineType, +            blank=True, +            null=True,              on_delete=models.SET_NULL, -            verbose_name="Type de saisine") -        instruction_deadline = models.DateField(_('Instruction deadline'), -                                                blank=True, null=True) -    total_surface = models.FloatField(_("Total surface (m2)"), -                                      blank=True, null=True) +            verbose_name="Type de saisine", +        ) +        instruction_deadline = models.DateField( +            _("Instruction deadline"), blank=True, null=True +        ) +    total_surface = models.FloatField(_("Total surface (m2)"), blank=True, null=True)      total_developed_surface = models.FloatField( -        _("Total developed surface (m2)"), blank=True, null=True) -    locality = models.CharField(_("Locality"), -                                max_length=100, null=True, blank=True) +        _("Total developed surface (m2)"), blank=True, null=True +    ) +    locality = models.CharField(_("Locality"), max_length=100, null=True, blank=True)      address = models.TextField(_("Main address"), blank=True, default="") -    postal_code = models.CharField(_("Main address - postal code"), -                                   max_length=10, null=True, blank=True) +    postal_code = models.CharField( +        _("Main address - postal code"), max_length=10, null=True, blank=True +    )      comment = models.TextField(_("Comment"), blank=True, default="")      # research archaeology -->      departments = models.ManyToManyField( -        Department, verbose_name=_("Departments"), blank=True) +        Department, verbose_name=_("Departments"), blank=True +    )      requested_operation_type = models.ForeignKey( -        OperationType, related_name='+', +        OperationType, +        related_name="+",          on_delete=models.SET_NULL, -        null=True, blank=True, verbose_name=_("Requested operation type")) +        null=True, +        blank=True, +        verbose_name=_("Requested operation type"), +    )      organization = models.ForeignKey( -        Organization, blank=True, null=True, verbose_name=_("Organization"), -        related_name='files', on_delete=models.SET_NULL) +        Organization, +        blank=True, +        null=True, +        verbose_name=_("Organization"), +        related_name="files", +        on_delete=models.SET_NULL, +    )      scientist = models.ForeignKey( -        Person, blank=True, null=True, related_name='scientist', -        on_delete=models.SET_NULL, verbose_name=_("Scientist in charge")) +        Person, +        blank=True, +        null=True, +        related_name="scientist", +        on_delete=models.SET_NULL, +        verbose_name=_("Scientist in charge"), +    )      research_comment = models.TextField( -        _("Research archaeology comment"), blank=True, default="") +        _("Research archaeology comment"), blank=True, default="" +    )      classified_area = models.NullBooleanField( -        _("Classified area"), blank=True, null=True) -    protected_area = models.NullBooleanField( -        _("Protected area"), blank=True, null=True) -    if settings.COUNTRY == 'fr': -        cira_advised = models.NullBooleanField( -            "Passage en CIRA", blank=True, null=True) +        _("Classified area"), blank=True, null=True +    ) +    protected_area = models.NullBooleanField(_("Protected area"), blank=True, null=True) +    if settings.COUNTRY == "fr": +        cira_advised = models.NullBooleanField("Passage en CIRA", blank=True, null=True)          mh_register = models.NullBooleanField( -            "Sur Monument Historique classé", blank=True, null=True) +            "Sur Monument Historique classé", blank=True, null=True +        )          mh_listing = models.NullBooleanField( -            "Sur Monument Historique inscrit", blank=True, null=True) +            "Sur Monument Historique inscrit", blank=True, null=True +        )      # <-- research archaeology      documents = models.ManyToManyField( -        Document, related_name="files", verbose_name=_("Documents"), -        blank=True) +        Document, related_name="files", verbose_name=_("Documents"), blank=True +    )      cached_label = models.TextField( -        _("Cached name"), blank=True, default="", db_index=True, +        _("Cached name"), +        blank=True, +        default="", +        db_index=True,          help_text=_("Generated automatically - do not edit"),      )      imported_line = models.TextField(_("Imported line"), blank=True, default="")      history = HistoricalRecords(bases=[HistoryModel])      GET_VALUES_EXTRA = ValueGetter.GET_VALUES_EXTRA + [ -        'general_contractor_address_1', -        'general_contractor_address_2', -        'general_contractor_address_3', -        'get_locality', +        "general_contractor_address_1", +        "general_contractor_address_2", +        "general_contractor_address_3", +        "get_locality",      ]      class Meta: @@ -390,9 +474,9 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,              ("delete_own_file", "Can delete own Archaeological file"),              ("close_file", "Can close File"),          ) -        ordering = ('cached_label',) +        ordering = ("cached_label",)          indexes = [ -            GinIndex(fields=['data']), +            GinIndex(fields=["data"]),          ]      @classmethod @@ -413,33 +497,29 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,      @property      def full_internal_ref(self): -        return "{}{}".format(settings.ISHTAR_FILE_PREFIX or '', -                              self.external_id or '') +        return "{}{}".format(settings.ISHTAR_FILE_PREFIX or "", self.external_id or "")      @property      def delay_date(self): -        cache_key, val = get_cache(self.__class__, [self.pk, 'delay_date']) +        cache_key, val = get_cache(self.__class__, [self.pk, "delay_date"])          if val:              return val          return self.update_delay_date(cache_key)      def update_delay_date(self, cache_key=None):          if not cache_key: -            cache_key, val = get_cache(self.__class__, -                                       [self.pk, 'delay_date']) +            cache_key, val = get_cache(self.__class__, [self.pk, "delay_date"])          date = self.reception_date          if not date:              date = datetime.date(2500, 1, 1) -        elif settings.COUNTRY == 'fr' and self.saisine_type \ -                and self.saisine_type.delay: +        elif settings.COUNTRY == "fr" and self.saisine_type and self.saisine_type.delay:              date += datetime.timedelta(days=self.saisine_type.delay)          cache.set(cache_key, date, settings.CACHE_TIMEOUT)          return date      @property      def has_adminact(self): -        cache_key, val = get_cache(self.__class__, [self.pk, -                                                    'has_adminact']) +        cache_key, val = get_cache(self.__class__, [self.pk, "has_adminact"])          if val:              return val          return self.update_has_admin_act(cache_key) @@ -447,54 +527,71 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,      @property      def get_locality(self):          return " - ".join( -            [getattr(self, k) for k in ('locality', 'address') -             if getattr(self, k)]) +            [getattr(self, k) for k in ("locality", "address") if getattr(self, k)] +        )      @property      def general_contractor_address_1(self): -        address = '' +        address = ""          if self.general_contractor:              if self.general_contractor.name: -                address = " ".join([ -                    str(getattr(self.general_contractor, key)) -                    for key in ('title', 'surname', 'name') -                    if getattr(self.general_contractor, key)]) +                address = " ".join( +                    [ +                        str(getattr(self.general_contractor, key)) +                        for key in ("title", "surname", "name") +                        if getattr(self.general_contractor, key) +                    ] +                )              elif self.general_contractor.raw_name:                  address = self.general_contractor.raw_name -        if not address and self.corporation_general_contractor and\ -                self.corporation_general_contractor.name: +        if ( +            not address +            and self.corporation_general_contractor +            and self.corporation_general_contractor.name +        ):              address = self.corporation_general_contractor.name          return address      @property      def general_contractor_address_2(self): -        address = '' +        address = ""          if self.general_contractor and self.general_contractor.address:              address = self.general_contractor.address              if self.general_contractor.address_complement:                  address += " " + self.general_contractor.address_complement -        if not address and self.corporation_general_contractor and\ -                self.corporation_general_contractor.address: +        if ( +            not address +            and self.corporation_general_contractor +            and self.corporation_general_contractor.address +        ):              address = self.corporation_general_contractor.address              if self.corporation_general_contractor.address_complement: -                address += " " + \ -                    self.corporation_general_contractor.address_complement +                address += " " + self.corporation_general_contractor.address_complement          return address      @property      def general_contractor_address_3(self): -        address = '' +        address = ""          if self.general_contractor and self.general_contractor.postal_code: -            address = " ".join([ -                getattr(self.general_contractor, key) -                for key in ('postal_code', 'town') -                if getattr(self.general_contractor, key)]) -        if not address and self.corporation_general_contractor and\ -                self.corporation_general_contractor.address: -            address = " ".join([ -                getattr(self.corporation_general_contractor, key) -                for key in ('postal_code', 'town') -                if getattr(self.corporation_general_contractor, key)]) +            address = " ".join( +                [ +                    getattr(self.general_contractor, key) +                    for key in ("postal_code", "town") +                    if getattr(self.general_contractor, key) +                ] +            ) +        if ( +            not address +            and self.corporation_general_contractor +            and self.corporation_general_contractor.address +        ): +            address = " ".join( +                [ +                    getattr(self.corporation_general_contractor, key) +                    for key in ("postal_code", "town") +                    if getattr(self.corporation_general_contractor, key) +                ] +            )          return address      @classmethod @@ -503,9 +600,9 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          similar = set()          for parcel in parcels:              q = cls.objects.filter( -                parcels__town__pk=parcel['town'], -                parcels__section=parcel['section'], -                parcels__parcel_number=parcel['parcel_number'] +                parcels__town__pk=parcel["town"], +                parcels__section=parcel["section"], +                parcels__parcel_number=parcel["parcel_number"],              )              if q.count():                  for fle in q.all(): @@ -514,53 +611,55 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,      def update_has_admin_act(self, cache_key=None):          if not cache_key: -            cache_key, val = get_cache(self.__class__, [self.pk, -                                                        'has_adminact']) -        has_adminact = self.administrative_act.exclude( -            act_type__txt_idx='a_receipt').count() or self.operations.count() +            cache_key, val = get_cache(self.__class__, [self.pk, "has_adminact"]) +        has_adminact = ( +            self.administrative_act.exclude(act_type__txt_idx="a_receipt").count() +            or self.operations.count() +        )          cache.set(cache_key, has_adminact, settings.CACHE_TIMEOUT)          return has_adminact      @classmethod      def get_short_menu_class(cls, pk): -        cache_key, val = get_cache(cls, [pk, 'short_class_name']) +        cache_key, val = get_cache(cls, [pk, "short_class_name"])          if val:              return val          q = cls.objects.filter(pk=pk)          if not q.count(): -            return '' +            return ""          item = q.all()[0]          return item.update_short_menu_class(cache_key)      def update_short_menu_class(self, cache_key=None):          if not cache_key: -            cache_key, val = get_cache(self.__class__, [self.pk, -                                                        'short_class_name']) -        cls = 'normal' -        if not self.file_type.txt_idx == 'preventive': +            cache_key, val = get_cache(self.__class__, [self.pk, "short_class_name"]) +        cls = "normal" +        if not self.file_type.txt_idx == "preventive":              cls = "blue"          elif not self.has_adminact and self.reception_date:              delta = datetime.date.today() - self.reception_date -            cls = 'red' +            cls = "red"              if self.saisine_type and self.saisine_type.delay:                  if delta.days <= (self.saisine_type.delay * 2 / 3): -                    cls = 'green' +                    cls = "green"                  elif delta.days <= self.saisine_type.delay: -                    cls = 'orange' +                    cls = "orange"          cache.set(cache_key, cls, settings.CACHE_TIMEOUT)          return cls      @classmethod -    def get_owns(cls, user, menu_filtr=None, limit=None, values=None, -                 get_short_menu_class=False): +    def get_owns( +        cls, user, menu_filtr=None, limit=None, values=None, get_short_menu_class=False +    ):          owns = super(File, cls).get_owns( -            user, limit=limit, values=values, -            get_short_menu_class=get_short_menu_class) +            user, limit=limit, values=values, get_short_menu_class=get_short_menu_class +        )          return cls._return_get_owns(owns, values, get_short_menu_class) -    def get_values(self, prefix='', no_values=False, filtr=None, **kwargs): +    def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):          values = super(File, self).get_values( -            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) +            prefix=prefix, no_values=no_values, filtr=filtr, **kwargs +        )          return get_values_town_related(self, prefix, values, filtr=filtr)      def render_parcels(self): @@ -580,16 +679,20 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,      def _generate_cached_label(self):          items = [self.get_town_label(), self.reference] -        items += [str(getattr(self, k)) -                  for k in ['internal_reference', 'name'] if getattr(self, k)] +        items += [ +            str(getattr(self, k)) +            for k in ["internal_reference", "name"] +            if getattr(self, k) +        ]          return settings.JOINT.join(items)      def grouped_parcels(self):          from archaeological_operations.models import Parcel +          return Parcel.grouped_parcels(list(self.parcels.all()))      def get_town_label(self): -        lbl = str(_('Multi-town')) +        lbl = str(_("Multi-town"))          if self.main_town:              lbl = self.main_town.name          elif self.towns.count() == 1: @@ -600,7 +703,7 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,      def get_department(self):          if not self.towns.count(): -            return '00' +            return "00"          return self.towns.all()[0].numero_insee[:2]      @classmethod @@ -608,24 +711,19 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          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()]          return [              { -                'in_charge': ishtaruser.person, -                'history_creator': ishtaruser.user_ptr, -                'towns__pk__in': town_ids +                "in_charge": ishtaruser.person, +                "history_creator": ishtaruser.user_ptr, +                "towns__pk__in": town_ids,              }, -            { -                'end_date__isnull': True -            } +            {"end_date__isnull": True},          ]      @classmethod      def get_query_owns(cls, ishtaruser): -        return cls._construct_query_own( -            '', cls._get_query_owns_dicts(ishtaruser) -        ) +        return cls._construct_query_own("", cls._get_query_owns_dicts(ishtaruser))      def is_active(self):          return not bool(self.end_date) @@ -650,9 +748,10 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          return acts      def update_raw_town_planning_service(self): -        if (self.raw_town_planning_service and not -            self.responsible_town_planning_service) or \ -           not self.responsible_town_planning_service: +        if ( +            self.raw_town_planning_service +            and not self.responsible_town_planning_service +        ) or not self.responsible_town_planning_service:              return False          current_lbl = ""          if self.raw_town_planning_service: @@ -664,28 +763,30 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          return current_lbl != self.raw_town_planning_service      def update_planning_service(self): -        if not self.responsible_town_planning_service or \ -           not self.responsible_town_planning_service.attached_to or \ -           self.planning_service: +        if ( +            not self.responsible_town_planning_service +            or not self.responsible_town_planning_service.attached_to +            or self.planning_service +        ):              return False -        self.planning_service = \ -            self.responsible_town_planning_service.attached_to +        self.planning_service = self.responsible_town_planning_service.attached_to          return True      def update_resp_planning_service(self): -        if not self.responsible_town_planning_service or \ -           self.responsible_town_planning_service.attached_to or \ -           not self.planning_service: +        if ( +            not self.responsible_town_planning_service +            or self.responsible_town_planning_service.attached_to +            or not self.planning_service +        ):              return False -        self.responsible_town_planning_service.attached_to = \ -            self.planning_service +        self.responsible_town_planning_service.attached_to = self.planning_service          self.responsible_town_planning_service.save()          return True      def update_raw_general_contractor(self): -        if (self.raw_general_contractor and not -           self.general_contractor) or \ -           not self.general_contractor: +        if ( +            self.raw_general_contractor and not self.general_contractor +        ) or not self.general_contractor:              return False          current_lbl = ""          if self.raw_general_contractor: @@ -697,45 +798,53 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          return current_lbl != self.raw_general_contractor      def update_corpo_general_contractor(self): -        if not self.general_contractor or \ -           self.general_contractor.attached_to \ -           == self.corporation_general_contractor: +        if ( +            not self.general_contractor +            or self.general_contractor.attached_to +            == self.corporation_general_contractor +        ):              return False          if self.general_contractor.attached_to: -            self.corporation_general_contractor = \ -                self.general_contractor.attached_to +            self.corporation_general_contractor = self.general_contractor.attached_to          else: -            self.general_contractor.attached_to = \ -                self.corporation_general_contractor +            self.general_contractor.attached_to = self.corporation_general_contractor              self.general_contractor.save()          return True      def get_extra_actions(self, request):          # url, base_text, icon, extra_text, extra css class, is a quick action          actions = super(File, self).get_extra_actions(request) -        if self.can_do(request, 'add_administrativeact'): +        if self.can_do(request, "add_administrativeact"):              actions += [ -                (reverse('file-add-adminact', args=[self.pk]), -                 _("Add associated administrative act"), "fa fa-plus", -                 _("admin. act"), "", False), +                ( +                    reverse("file-add-adminact", args=[self.pk]), +                    _("Add associated administrative act"), +                    "fa fa-plus", +                    _("admin. act"), +                    "", +                    False, +                ),              ] -        if self.can_do(request, 'add_operation'): +        if self.can_do(request, "add_operation"):              actions += [                  ( -                    reverse('file-add-operation', args=[self.pk]), +                    reverse("file-add-operation", args=[self.pk]),                      _("Add operation"),                      "fa fa-plus",                      _("operation"),                      "", -                    False +                    False,                  )              ]          return actions      def save(self, *args, **kwargs):          returned = super(File, self).save(*args, **kwargs) -        if not getattr(self, '_no_new_add', None) and self.main_town and \ -                self.main_town not in list(self.towns.all()): +        if ( +            not getattr(self, "_no_new_add", None) +            and self.main_town +            and self.main_town not in list(self.towns.all()) +        ):              self._no_new_add = True              self.towns.add(self.main_town)          updated = self.update_raw_town_planning_service() @@ -745,7 +854,7 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, CompleteIdentifierItem,          updated += self.update_corpo_general_contractor()          if not self.external_id or self.auto_external_id: -            external_id = get_generated_id('file_external_id', self) +            external_id = get_generated_id("file_external_id", self)              if external_id != self.external_id:                  updated = True                  self.auto_external_id = True @@ -768,14 +877,14 @@ m2m_changed.connect(cached_label_changed, sender=File.towns.through)  post_save.connect(cached_label_changed, sender=File)  for attr in File.HISTORICAL_M2M: -    m2m_changed.connect(m2m_historization_changed, -                        sender=getattr(File, attr).through) +    m2m_changed.connect(m2m_historization_changed, sender=getattr(File, attr).through)  class FileByDepartment(models.Model):      """      Database view for dashboard      """ +      CREATE_SQL = """      CREATE VIEW file_department (id, department_id, file_id) as          select town."id", town."departement_id", file_towns."file_id" @@ -790,13 +899,17 @@ class FileByDepartment(models.Model):      DROP VIEW IF EXISTS file_department;      """      file = models.ForeignKey(File, verbose_name=_("File")) -    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 = 'file_department' +        db_table = "file_department"      def __str__(self):          return "{} - {}".format(self.file, self.department) @@ -805,119 +918,146 @@ class FileByDepartment(models.Model):  class FileDashboard:      def __init__(self):          from archaeological_operations.models import AdministrativeAct +          main_dashboard = Dashboard(File)          self.total_number = main_dashboard.total_number -        types = File.objects.values('file_type', 'file_type__label') -        self.types = types.annotate(number=Count('pk')).order_by('file_type') +        types = File.objects.values("file_type", "file_type__label") +        self.types = types.annotate(number=Count("pk")).order_by("file_type") -        by_year = File.objects.extra( -            {'date': "date_trunc('year', creation_date)"}) -        self.by_year = by_year.values('date')\ -                              .annotate(number=Count('pk')).order_by('-date') +        by_year = File.objects.extra({"date": "date_trunc('year', creation_date)"}) +        self.by_year = ( +            by_year.values("date").annotate(number=Count("pk")).order_by("-date") +        )          now = datetime.date.today()          limit = datetime.date(now.year, now.month, 1) - datetime.timedelta(365)          by_month = File.objects.filter(creation_date__gt=limit).extra( -            {'date': "date_trunc('month', creation_date)"}) -        self.by_month = by_month.values('date')\ -                                .annotate(number=Count('pk')).order_by('-date') +            {"date": "date_trunc('month', creation_date)"} +        ) +        self.by_month = ( +            by_month.values("date").annotate(number=Count("pk")).order_by("-date") +        )          # research          self.research = {} -        prog_type = FileType.objects.get(txt_idx='prog') +        prog_type = FileType.objects.get(txt_idx="prog")          researchs = File.objects.filter(file_type=prog_type) -        self.research['total_number'] = researchs.count() -        by_year = researchs.extra( -            {'date': "date_trunc('year', creation_date)"} +        self.research["total_number"] = researchs.count() +        by_year = researchs.extra({"date": "date_trunc('year', creation_date)"}) +        self.research["by_year"] = ( +            by_year.values("date").annotate(number=Count("pk")).order_by("-date") +        ) +        by_month = researchs.filter(creation_date__gt=limit).extra( +            {"date": "date_trunc('month', creation_date)"} +        ) +        self.research["by_month"] = ( +            by_month.values("date").annotate(number=Count("pk")).order_by("-date") +        ) + +        self.research["by_dpt"] = ( +            FileByDepartment.objects.filter( +                file__file_type=prog_type, department__isnull=False +            ) +            .values("department__label") +            .annotate(number=Count("file")) +            .order_by("department__label")          ) -        self.research['by_year'] = by_year.values('date')\ -                                          .annotate(number=Count('pk'))\ -                                          .order_by('-date') -        by_month = researchs.filter(creation_date__gt=limit)\ -            .extra({'date': "date_trunc('month', creation_date)"}) -        self.research['by_month'] = by_month.values('date')\ -                                            .annotate(number=Count('pk'))\ -                                            .order_by('-date') - -        self.research['by_dpt'] = FileByDepartment.objects\ -            .filter(file__file_type=prog_type, department__isnull=False)\ -            .values('department__label')\ -            .annotate(number=Count('file'))\ -            .order_by('department__label')          FileTown = File.towns.through -        self.research['towns'] = FileTown.objects\ -            .filter(file__file_type=prog_type)\ -            .values('town__name')\ -            .annotate(number=Count('file'))\ -            .order_by('-number', 'town__name')[:10] +        self.research["towns"] = ( +            FileTown.objects.filter(file__file_type=prog_type) +            .values("town__name") +            .annotate(number=Count("file")) +            .order_by("-number", "town__name")[:10] +        )          # rescue -        rescue_type = FileType.objects.get(txt_idx='preventive') +        rescue_type = FileType.objects.get(txt_idx="preventive")          rescues = File.objects.filter(file_type=rescue_type)          self.rescue = {} -        self.rescue['total_number'] = rescues.count() -        self.rescue['saisine'] = rescues.values('saisine_type__label')\ -            .annotate(number=Count('pk')).order_by('saisine_type__label') -        self.rescue['administrative_act'] = AdministrativeAct.objects\ -            .filter(associated_file__isnull=False)\ -            .values('act_type__label')\ -            .annotate(number=Count('pk'))\ -            .order_by('act_type__pk') - -        by_year = rescues.extra({'date': "date_trunc('year', creation_date)"}) -        self.rescue['by_year'] = by_year.values('date')\ -            .annotate(number=Count('pk')).order_by('-date') -        by_month = rescues.filter(creation_date__gt=limit)\ -            .extra({'date': "date_trunc('month', creation_date)"}) -        self.rescue['by_month'] = by_month.values('date')\ -                                          .annotate(number=Count('pk'))\ -                                          .order_by('-date') - -        self.rescue['by_dpt'] = FileByDepartment.objects\ -            .filter(file__file_type=rescue_type, department__isnull=False)\ -            .values('department__label')\ -            .annotate(number=Count('file'))\ -            .order_by('department__label') -        self.rescue['towns'] = FileTown.objects\ -            .filter(file__file_type=rescue_type)\ -            .values('town__name')\ -            .annotate(number=Count('file'))\ -            .order_by('-number', 'town__name')[:10] - -        self.rescue['with_associated_operation'] = rescues\ -            .filter(operations__isnull=False).count() - -        if self.rescue['total_number']: -            self.rescue['with_associated_operation_percent'] = round( -                float(self.rescue['with_associated_operation']) -                / self.rescue['total_number'] * 100, 2) - -        by_year_operationnal = rescues.filter(operations__isnull=False)\ -            .extra({'date': 'date_trunc(\'year\', ' -                            '"archaeological_files_file".creation_date)'}) -        by_year_operationnal = by_year_operationnal.values('date')\ -            .annotate(number=Count('pk')).order_by('-date') +        self.rescue["total_number"] = rescues.count() +        self.rescue["saisine"] = ( +            rescues.values("saisine_type__label") +            .annotate(number=Count("pk")) +            .order_by("saisine_type__label") +        ) +        self.rescue["administrative_act"] = ( +            AdministrativeAct.objects.filter(associated_file__isnull=False) +            .values("act_type__label") +            .annotate(number=Count("pk")) +            .order_by("act_type__pk") +        ) + +        by_year = rescues.extra({"date": "date_trunc('year', creation_date)"}) +        self.rescue["by_year"] = ( +            by_year.values("date").annotate(number=Count("pk")).order_by("-date") +        ) +        by_month = rescues.filter(creation_date__gt=limit).extra( +            {"date": "date_trunc('month', creation_date)"} +        ) +        self.rescue["by_month"] = ( +            by_month.values("date").annotate(number=Count("pk")).order_by("-date") +        ) + +        self.rescue["by_dpt"] = ( +            FileByDepartment.objects.filter( +                file__file_type=rescue_type, department__isnull=False +            ) +            .values("department__label") +            .annotate(number=Count("file")) +            .order_by("department__label") +        ) +        self.rescue["towns"] = ( +            FileTown.objects.filter(file__file_type=rescue_type) +            .values("town__name") +            .annotate(number=Count("file")) +            .order_by("-number", "town__name")[:10] +        ) + +        self.rescue["with_associated_operation"] = rescues.filter( +            operations__isnull=False +        ).count() + +        if self.rescue["total_number"]: +            self.rescue["with_associated_operation_percent"] = round( +                float(self.rescue["with_associated_operation"]) +                / self.rescue["total_number"] +                * 100, +                2, +            ) + +        by_year_operationnal = rescues.filter(operations__isnull=False).extra( +            {"date": "date_trunc('year', " '"archaeological_files_file".creation_date)'} +        ) +        by_year_operationnal = ( +            by_year_operationnal.values("date") +            .annotate(number=Count("pk")) +            .order_by("-date") +        )          percents, idx = [], 0 -        for dct in self.rescue['by_year']: +        for dct in self.rescue["by_year"]:              if idx >= len(by_year_operationnal):                  break -            if by_year_operationnal[idx]['date'] != dct['date'] or\ -               not dct['number']: +            if by_year_operationnal[idx]["date"] != dct["date"] or not dct["number"]:                  continue -            val = round(float(by_year_operationnal[idx]['number']) / -                        dct['number'] * 100, 2) -            percents.append({'date': dct['date'], 'number': val}) -        self.rescue['operational_by_year'] = percents - -        self.rescue['surface_by_town'] = FileTown.objects\ -            .filter(file__file_type=rescue_type)\ -            .values('town__name')\ -            .annotate(number=Sum('file__total_surface'))\ -            .order_by('-number', 'town__name')[:10] -        self.rescue['surface_by_dpt'] = FileByDepartment.objects\ -            .filter(file__file_type=rescue_type, department__isnull=False)\ -            .values('department__label')\ -            .annotate(number=Sum('file__total_surface'))\ -            .order_by('department__label') +            val = round( +                float(by_year_operationnal[idx]["number"]) / dct["number"] * 100, 2 +            ) +            percents.append({"date": dct["date"], "number": val}) +        self.rescue["operational_by_year"] = percents + +        self.rescue["surface_by_town"] = ( +            FileTown.objects.filter(file__file_type=rescue_type) +            .values("town__name") +            .annotate(number=Sum("file__total_surface")) +            .order_by("-number", "town__name")[:10] +        ) +        self.rescue["surface_by_dpt"] = ( +            FileByDepartment.objects.filter( +                file__file_type=rescue_type, department__isnull=False +            ) +            .values("department__label") +            .annotate(number=Sum("file__total_surface")) +            .order_by("department__label") +        ) diff --git a/archaeological_files/tests.py b/archaeological_files/tests.py index 1aab1b2c4..bf9ac14c0 100644 --- a/archaeological_files/tests.py +++ b/archaeological_files/tests.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> @@ -25,25 +25,37 @@ from django.contrib.auth.models import User  from django.core.urlresolvers import reverse  from django.test.client import Client -from ishtar_common.tests import TestCase, COMMON_FIXTURES, create_superuser, \ -    AutocompleteTestBase, AcItem +from ishtar_common.tests import ( +    TestCase, +    COMMON_FIXTURES, +    create_superuser, +    AutocompleteTestBase, +    AcItem, +)  from ishtar_common.models import Town, IshtarSiteProfile  from archaeological_files import models -from archaeological_operations.models import Parcel, ParcelOwner, ActType, \ -    AdministrativeAct +from archaeological_operations.models import ( +    Parcel, +    ParcelOwner, +    ActType, +    AdministrativeAct, +)  from ishtar_common.tests import FILE_TOWNS_FIXTURES  from archaeological_operations.tests import OperationInitTest, FileInit  def create_administrativact(user, fle):      act_type, created = ActType.objects.get_or_create( -        txt_idx='act_type_F', intented_to='F') -    dct = {'history_modifier': user, -           'act_type': act_type, -           'associated_file': fle, -           'signature_date': datetime.date(2017, 7, 10), -           'index': 22} +        txt_idx="act_type_F", intented_to="F" +    ) +    dct = { +        "history_modifier": user, +        "act_type": act_type, +        "associated_file": fle, +        "signature_date": datetime.date(2017, 7, 10), +        "index": 22, +    }      adminact, created = AdministrativeAct.objects.get_or_create(**dct)      return [act_type], [adminact] @@ -59,26 +71,28 @@ class FileTest(TestCase, FileInit):      def test_external_id(self):          self.assertEqual(              self.item.external_id, -            "{}-{}".format(self.item.year, -                           self.item.numeric_reference)) +            "{}-{}".format(self.item.year, self.item.numeric_reference), +        )      def test_cached_label(self):          self.item = models.File.objects.get(pk=self.item.pk)          # localisation fix          lbls = [] -        for town_lbl in ('No town', 'Pas de commune'): -            lbls.append(settings.JOINT.join( -                [town_lbl, self.item.external_id, -                 self.item.internal_reference])) +        for town_lbl in ("No town", "Pas de commune"): +            lbls.append( +                settings.JOINT.join( +                    [town_lbl, self.item.external_id, self.item.internal_reference] +                ) +            )          self.assertIn(self.item.cached_label, lbls) -        default_town = Town.objects.create(name="Paris", numero_insee='75001') +        default_town = Town.objects.create(name="Paris", numero_insee="75001")          self.item.towns.add(default_town)          # manually done inside wizards          self.item._cached_label_checked = False          self.item._test = True          self.item.save()          self.item = models.File.objects.get(pk=self.item.pk) -        lbl = lbls[0].replace('No town', 'Paris') +        lbl = lbls[0].replace("No town", "Paris")          self.assertEqual(self.item.cached_label, lbl)      def testAddAndGetHistorized(self): @@ -107,7 +121,7 @@ class FileTest(TestCase, FileInit):          Test creator association          """          self.assertEqual(self.item.history_creator, self.o_user) -        altuser, created = User.objects.get_or_create(username='altusername') +        altuser, created = User.objects.get_or_create(username="altusername")          item = models.File.objects.get(pk=self.item.pk)          item.internal_reference = "Unité_Test"          item.history_modifier = altuser @@ -142,22 +156,22 @@ class FileTest(TestCase, FileInit):          self.assertEqual(self.item.history.count(), nb_hist)          new_values = self.item.values()          for k in initial_values.keys(): -            if k in ('last_modified', 'search_vector', 'qrcode'): +            if k in ("last_modified", "search_vector", "qrcode"):                  continue -            elif k == 'history_m2m' and not initial_values[k]: -                initial_values[k] = dict( -                    [(j, []) for j in models.File.HISTORICAL_M2M] -                ) -            self.assertTrue(k in new_values, -                            msg='%s not in new values' % k) +            elif k == "history_m2m" and not initial_values[k]: +                initial_values[k] = dict([(j, []) for j in models.File.HISTORICAL_M2M]) +            self.assertTrue(k in new_values, msg="%s not in new values" % k)              self.assertEqual( -                new_values[k], initial_values[k], -                msg="for %s: %s != %s" % (k, str(new_values[k]), -                                          str(initial_values[k]))) +                new_values[k], +                initial_values[k], +                msg="for %s: %s != %s" +                % (k, str(new_values[k]), str(initial_values[k])), +            )      def testRESTGetFile(self):          response = self.client.post( -            '/get-file/', {'numeric_reference': self.item.numeric_reference}) +            "/get-file/", {"numeric_reference": self.item.numeric_reference} +        )          self.assertEqual(response.status_code, 200)          data = json.loads(response.content.decode())          # not allowed -> no data @@ -165,11 +179,12 @@ class FileTest(TestCase, FileInit):          self.login_as_superuser()          response = self.client.post( -            '/get-file/', {'numeric_reference': self.item.numeric_reference}) +            "/get-file/", {"numeric_reference": self.item.numeric_reference} +        )          self.assertEqual(response.status_code, 200)          data = json.loads(response.content.decode()) -        self.assertTrue('recordsTotal' in data) -        self.assertEqual(data['recordsTotal'], 1) +        self.assertTrue("recordsTotal" in data) +        self.assertEqual(data["recordsTotal"], 1)      def testRESTGetOldFile(self):          initial_ref = self.item.internal_reference @@ -180,8 +195,8 @@ class FileTest(TestCase, FileInit):          item.history_modifier = self.user          item.save()          response = self.client.post( -            '/get-file/', -            {'numeric_reference': item.numeric_reference, 'old': 1}) +            "/get-file/", {"numeric_reference": item.numeric_reference, "old": 1} +        )          self.assertEqual(response.status_code, 200)          data = json.loads(response.content.decode())          # not allowed -> no data @@ -189,17 +204,17 @@ class FileTest(TestCase, FileInit):          self.login_as_superuser()          response = self.client.post( -            '/get-file/', -            {'numeric_reference': item.numeric_reference, 'old': 1}) +            "/get-file/", {"numeric_reference": item.numeric_reference, "old": 1} +        )          self.assertEqual(response.status_code, 200)          data = json.loads(response.content.decode()) -        self.assertIn('recordsTotal', data) -        self.assertEqual(data['recordsTotal'], 1) -        self.assertEqual(data['rows'][0]['internal_reference'], initial_ref) +        self.assertIn("recordsTotal", data) +        self.assertEqual(data["recordsTotal"], 1) +        self.assertEqual(data["rows"][0]["internal_reference"], initial_ref)      def testPostDeleteParcels(self):          fle = self.item -        town = Town.objects.create(name='plouf', numero_insee='20000') +        town = Town.objects.create(name="plouf", numero_insee="20000")          parcel = Parcel.objects.create(town=town)          parcel_nb = Parcel.objects.count()          fle.parcels.add(parcel) @@ -220,15 +235,15 @@ class FileTest(TestCase, FileInit):      def test_show(self):          c = Client() -        url = 'show-file' +        url = "show-file"          pk = self.item.pk -        response = self.client.get(reverse(url, kwargs={'pk': pk})) +        response = self.client.get(reverse(url, kwargs={"pk": pk}))          self.assertEqual(response.status_code, 200)          # empty content when not allowed          self.assertEqual(response.content.decode(), "")          self.login_as_superuser() -        response = self.client.get(reverse(url, kwargs={'pk': pk})) +        response = self.client.get(reverse(url, kwargs={"pk": pk}))          self.assertEqual(response.status_code, 200)          self.assertIn('class="card sheet"', response.content.decode()) @@ -249,14 +264,17 @@ class FileOperationTest(TestCase, OperationInitTest, FileInit):          for p in range(0, 10):              parcel = Parcel.objects.create(                  parcel_number=str(p), -                section='YY', +                section="YY",                  town=default_town, -                operation=self.operation) +                operation=self.operation, +            )              if p == 1:                  ParcelOwner.objects.create( -                    owner=self.extra_models['person'], -                    parcel=parcel, start_date=datetime.date.today(), -                    end_date=datetime.date.today()) +                    owner=self.extra_models["person"], +                    parcel=parcel, +                    start_date=datetime.date.today(), +                    end_date=datetime.date.today(), +                )          initial_nb = self.item.parcels.count()          # no parcel on the file -> new parcels are copied from the          # operation @@ -269,25 +287,30 @@ class FileOperationTest(TestCase, OperationInitTest, FileInit):          # when attaching parcel from a file to an operation, copy is done          parcel = Parcel.objects.create( -            parcel_number='42', section='ZZ', -            town=default_town, associated_file=self.item) +            parcel_number="42", +            section="ZZ", +            town=default_town, +            associated_file=self.item, +        )          ParcelOwner.objects.create( -            owner=self.extra_models['person'], -            parcel=parcel, start_date=datetime.date.today(), -            end_date=datetime.date.today()) +            owner=self.extra_models["person"], +            parcel=parcel, +            start_date=datetime.date.today(), +            end_date=datetime.date.today(), +        )          parcel.operation = self.operation          parcel.save()          # double reference to operation and associated_file is deleted          self.assertEqual(parcel.operation, None)          # now 2 objects with the same parameters -        q = Parcel.objects.filter(parcel_number='42', section='ZZ', -                                  town=default_town) +        q = Parcel.objects.filter(parcel_number="42", section="ZZ", town=default_town)          self.assertEqual(q.count(), 2)          q = q.filter(operation=self.operation, associated_file=None)          self.assertEqual(q.count(), 1)          # parcel owner well attached -        q = ParcelOwner.objects.filter(parcel__operation=self.operation, -                                       parcel__parcel_number='42') +        q = ParcelOwner.objects.filter( +            parcel__operation=self.operation, parcel__parcel_number="42" +        )          self.assertEqual(q.count(), 1) @@ -301,7 +324,7 @@ class DashboardTest(TestCase, FileInit):          self.create_file()      def test_dashboard(self): -        url = 'dashboard-file' +        url = "dashboard-file"          c = Client()          c.login(username=self.username, password=self.password) @@ -312,13 +335,11 @@ class DashboardTest(TestCase, FileInit):  class AutocompleteTest(AutocompleteTestBase, TestCase):      fixtures = FILE_TOWNS_FIXTURES      models = [ -        AcItem(models.File, 'autocomplete-file', -               prepare_func="create_file"), +        AcItem(models.File, "autocomplete-file", prepare_func="create_file"),      ]      def create_file(self, base_name):          item, __ = models.File.objects.get_or_create( -            name=base_name, -            file_type=models.FileType.objects.all()[0] +            name=base_name, file_type=models.FileType.objects.all()[0]          )          return item, None diff --git a/archaeological_files/urls.py b/archaeological_files/urls.py index d6db8e763..b245b0aea 100644 --- a/archaeological_files/urls.py +++ b/archaeological_files/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,73 +27,114 @@ from archaeological_operations.views import administrativeactfile_document  # forms:  urlpatterns = [ -    url(r'file_administrativeactfil_search/(?P<step>.+)?$', -        check_rights(['change_administrativeact'])( -            views.file_administrativeactfile_search_wizard), -        name='file_administrativeactfile_search'), -    url(r'file_administrativeactfil/(?P<step>.+)?$', -        check_rights(['change_administrativeact'])( -            views.file_administrativeactfile_wizard), -        name='file_administrativeactfile'), -    url(r'file_administrativeactfile_modify/(?P<pk>.+)/$', +    url( +        r"file_administrativeactfil_search/(?P<step>.+)?$", +        check_rights(["change_administrativeact"])( +            views.file_administrativeactfile_search_wizard +        ), +        name="file_administrativeactfile_search", +    ), +    url( +        r"file_administrativeactfil/(?P<step>.+)?$", +        check_rights(["change_administrativeact"])( +            views.file_administrativeactfile_wizard +        ), +        name="file_administrativeactfile", +    ), +    url( +        r"file_administrativeactfile_modify/(?P<pk>.+)/$",          views.file_administrativeactfile_modify, -        name='file_administrativeactfile_modify'), -    url(r'file_administrativeactfil_deletion/(?P<step>.+)?$', -        check_rights(['change_administrativeact'])( -            views.file_administrativeactfile_deletion_wizard), -        name='file_administrativeactfile_deletion'), -    url(r'file_administrativeactfil_modification/(?P<step>.+)?$', -        check_rights(['change_administrativeact'])( -            views.file_administrativeactfile_modification_wizard), -        name='file_administrativeactfile_modification'), -    url(r'file_administrativeactfile_delete/(?P<pk>.+)/$', +        name="file_administrativeactfile_modify", +    ), +    url( +        r"file_administrativeactfil_deletion/(?P<step>.+)?$", +        check_rights(["change_administrativeact"])( +            views.file_administrativeactfile_deletion_wizard +        ), +        name="file_administrativeactfile_deletion", +    ), +    url( +        r"file_administrativeactfil_modification/(?P<step>.+)?$", +        check_rights(["change_administrativeact"])( +            views.file_administrativeactfile_modification_wizard +        ), +        name="file_administrativeactfile_modification", +    ), +    url( +        r"file_administrativeactfile_delete/(?P<pk>.+)/$",          views.file_administrativeact_delete, -        name='delete-administrativeact-file'), -    url(r'file_search/(?P<step>.+)?$', -        check_rights(['view_file', 'view_own_file'])( -            views.file_search_wizard), -        name='file_search'), -    url(r'^file_creation/(?P<step>.+)?$', -        check_rights(['add_file'])( -            views.file_creation_wizard), name='file_creation'), -    url(r'^file_modification/(?P<step>.+)?$', -        check_rights(['change_file', 'change_own_file'])( -            views.file_modification_wizard), name='file_modification'), -    url(r'^file_modify/(?P<pk>.+)/$', views.file_modify, name='file_modify'), -    url(r'^file_closing/(?P<step>.+)?$', -        check_rights(['change_file'])( -            views.file_closing_wizard), -        name='file_closing'), -    url(r'file_deletion/(?P<step>.+)?$', -        check_rights(['delete_file', 'delete_own_file'])( -            views.file_deletion_wizard), -        name='file_deletion'), -    url(r'^file_delete/(?P<pk>.+)/$', views.file_delete, name='delete-file'), -    url(r'autocomplete-file/$', views.autocomplete_file, -        name='autocomplete-file'), -    url(r'get-file/(?P<type>.+)?$', views.get_file, -        name='get-file'), -    url(r'get-file-full/(?P<type>.+)?$', views.get_file, -        name='get-file-full', kwargs={'full': True}), -    url(r'get-file-shortcut/(?P<type>.+)?$', -        views.get_file, name='get-file-shortcut', -        kwargs={'full': 'shortcut'}), -    url(r'get-administrativeactfile/(?P<type>.+)?$', -        views.get_administrativeactfile, name='get-administrativeactfile'), -    url(r'show-file(?:/(?P<pk>.+))?/(?P<type>.+)?$', views.show_file, -        name='show-file'), -    url(r'show-historized-file/(?P<pk>.+)?/(?P<date>.+)?$', -        views.show_file, name='show-historized-file'), -    url(r'revert-file/(?P<pk>.+)/(?P<date>.+)$', -        views.revert_file, name='revert-file'), -    url(r'^file-add-adminact/(?P<pk>[0-9-]+)/$', -        check_rights(['add_administrativeact'])(views.file_adminact_add), -        name='file-add-adminact'), -    url(r'dashboard_file/$', views.dashboard_file, name='dashboard-file'), -    url(r'file_administrativeact_document/$', +        name="delete-administrativeact-file", +    ), +    url( +        r"file_search/(?P<step>.+)?$", +        check_rights(["view_file", "view_own_file"])(views.file_search_wizard), +        name="file_search", +    ), +    url( +        r"^file_creation/(?P<step>.+)?$", +        check_rights(["add_file"])(views.file_creation_wizard), +        name="file_creation", +    ), +    url( +        r"^file_modification/(?P<step>.+)?$", +        check_rights(["change_file", "change_own_file"])( +            views.file_modification_wizard +        ), +        name="file_modification", +    ), +    url(r"^file_modify/(?P<pk>.+)/$", views.file_modify, name="file_modify"), +    url( +        r"^file_closing/(?P<step>.+)?$", +        check_rights(["change_file"])(views.file_closing_wizard), +        name="file_closing", +    ), +    url( +        r"file_deletion/(?P<step>.+)?$", +        check_rights(["delete_file", "delete_own_file"])(views.file_deletion_wizard), +        name="file_deletion", +    ), +    url(r"^file_delete/(?P<pk>.+)/$", views.file_delete, name="delete-file"), +    url(r"autocomplete-file/$", views.autocomplete_file, name="autocomplete-file"), +    url(r"get-file/(?P<type>.+)?$", views.get_file, name="get-file"), +    url( +        r"get-file-full/(?P<type>.+)?$", +        views.get_file, +        name="get-file-full", +        kwargs={"full": True}, +    ), +    url( +        r"get-file-shortcut/(?P<type>.+)?$", +        views.get_file, +        name="get-file-shortcut", +        kwargs={"full": "shortcut"}, +    ), +    url( +        r"get-administrativeactfile/(?P<type>.+)?$", +        views.get_administrativeactfile, +        name="get-administrativeactfile", +    ), +    url(r"show-file(?:/(?P<pk>.+))?/(?P<type>.+)?$", views.show_file, name="show-file"), +    url( +        r"show-historized-file/(?P<pk>.+)?/(?P<date>.+)?$", +        views.show_file, +        name="show-historized-file", +    ), +    url(r"revert-file/(?P<pk>.+)/(?P<date>.+)$", views.revert_file, name="revert-file"), +    url( +        r"^file-add-adminact/(?P<pk>[0-9-]+)/$", +        check_rights(["add_administrativeact"])(views.file_adminact_add), +        name="file-add-adminact", +    ), +    url(r"dashboard_file/$", views.dashboard_file, name="dashboard-file"), +    url( +        r"file_administrativeact_document/$",          administrativeactfile_document, -        name='file-administrativeact-document', kwargs={'file': True}), -    url(r'^file-add-operation/(?P<pk>[0-9-]+)/$', -        check_rights(['add_operation'])(views.file_add_operation), -        name='file-add-operation'), +        name="file-administrativeact-document", +        kwargs={"file": True}, +    ), +    url( +        r"^file-add-operation/(?P<pk>[0-9-]+)/$", +        check_rights(["add_operation"])(views.file_add_operation), +        name="file-add-operation", +    ),  ] diff --git a/archaeological_files/views.py b/archaeological_files/views.py index dcd1387f9..35bd9d7c8 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3  # -*- coding: utf-8 -*-  # Copyright (C) 2010-2016  Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> @@ -29,14 +29,22 @@ from ishtar_common.utils import ugettext_lazy as _  from ishtar_common.views import wizard_is_available  from ishtar_common.views_item import get_item, show_item, revert_item -from archaeological_operations.wizards import AdministrativeActDeletionWizard, \ -    is_preventive, is_not_preventive +from archaeological_operations.wizards import ( +    AdministrativeActDeletionWizard, +    is_preventive, +    is_not_preventive, +)  from ishtar_common.wizards import SearchWizard  from archaeological_files import wizards -from archaeological_files.wizards import FileWizard, \ -    FileModificationWizard, FileClosingWizard, FileDeletionWizard, \ -    FileAdministrativeActWizard, FileEditAdministrativeActWizard +from archaeological_files.wizards import ( +    FileWizard, +    FileModificationWizard, +    FileClosingWizard, +    FileDeletionWizard, +    FileAdministrativeActWizard, +    FileEditAdministrativeActWizard, +)  from archaeological_operations.wizards import OperationWizard  from archaeological_operations.views import operation_creation_wizard @@ -52,19 +60,25 @@ RE_YEAR_INDEX = re.compile(r"([1-2][0-9]{3})-([0-9]+)")  # eg.: 2014-123  def autocomplete_file(request): -    if not request.user.has_perm('ishtar_common.view_file', models.File) and \ -       not request.user.has_perm('ishtar_common.view_own_file', models.File) \ -       and not request.user.ishtaruser.has_right('file_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_file", models.File) +        and not request.user.has_perm("ishtar_common.view_own_file", models.File) +        and not request.user.ishtaruser.has_right( +            "file_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(' '): -        extra = Q(internal_reference__icontains=q) | \ -            Q(towns__name__icontains=q) | \ -            Q(address__icontains=q) | Q(name__icontains=q) +    for q in q.split(" "): +        extra = ( +            Q(internal_reference__icontains=q) +            | Q(towns__name__icontains=q) +            | Q(address__icontains=q) +            | Q(name__icontains=q) +        )          try:              int(q)              extra = extra | Q(year=q) | Q(numeric_reference=q) @@ -77,100 +91,121 @@ def autocomplete_file(request):          query = query & extra      limit = 20      files = models.File.objects.filter(query)[:limit] -    data = json.dumps([{'id': file.pk, 'value': str(file)} -                       for file in files]) -    return HttpResponse(data, content_type='text/plain') +    data = json.dumps([{"id": file.pk, "value": str(file)} for file in files]) +    return HttpResponse(data, content_type="text/plain") -get_file = get_item(models.File, 'get_file', 'file', -                    search_form=forms.FileSelect) +get_file = get_item(models.File, "get_file", "file", search_form=forms.FileSelect)  revert_file = revert_item(models.File)  def extra_file_dct(request, item):      dct = {} -    if (request.user.has_perm('ishtar_common.add_operation', Operation) -       or request.user.ishtaruser.has_right('add_operation')): -        dct['can_add_operation'] = True +    if request.user.has_perm( +        "ishtar_common.add_operation", Operation +    ) or request.user.ishtaruser.has_right("add_operation"): +        dct["can_add_operation"] = True      return dct -show_file = show_item(models.File, 'file', extra_dct=extra_file_dct) + +show_file = show_item(models.File, "file", extra_dct=extra_file_dct)  get_administrativeactfile = get_item( -    AdministrativeAct, 'get_administrativeactfile', 'administrativeactfile', -    base_request={"associated_file__pk__isnull": False}) +    AdministrativeAct, +    "get_administrativeactfile", +    "administrativeactfile", +    base_request={"associated_file__pk__isnull": False}, +)  def dashboard_file(request, *args, **kwargs):      """      Main dashboard      """ -    dct = {'dashboard': models.FileDashboard()} -    return render(request, 'ishtar/dashboards/dashboard_file.html', dct) +    dct = {"dashboard": models.FileDashboard()} +    return render(request, "ishtar/dashboards/dashboard_file.html", dct) +  file_search_wizard = wizards.FileSearch.as_view( -    [('general-file_search', forms.FileFormSelection)], -    label=_("File search"), url_name='file_search',) +    [("general-file_search", forms.FileFormSelection)], +    label=_("File search"), +    url_name="file_search", +)  file_creation_wizard = wizards.FileWizard.as_view( -    [('general-file_creation', forms.FileFormGeneral), -     ('towns-file_creation', TownFormset), -     ('parcels-file_creation', forms.ParcelFormset), -     ('preventive-file_creation', forms.FileFormPreventive), -     ('research-file_creation', forms.FileFormResearch), -     ('final-file_creation', forms.FinalForm)], +    [ +        ("general-file_creation", forms.FileFormGeneral), +        ("towns-file_creation", TownFormset), +        ("parcels-file_creation", forms.ParcelFormset), +        ("preventive-file_creation", forms.FileFormPreventive), +        ("research-file_creation", forms.FileFormResearch), +        ("final-file_creation", forms.FinalForm), +    ],      label=_("New file"),      condition_dict={ -        'preventive-file_creation': -            is_preventive('general-file_creation', models.FileType, -                          type_key='file_type'), -        'research-file_creation': -            is_not_preventive('general-file_creation', models.FileType, -                              type_key='file_type'), +        "preventive-file_creation": is_preventive( +            "general-file_creation", models.FileType, type_key="file_type" +        ), +        "research-file_creation": is_not_preventive( +            "general-file_creation", models.FileType, type_key="file_type" +        ),      }, -    url_name='file_creation',) +    url_name="file_creation", +)  file_modification_wizard = wizards.FileModificationWizard.as_view( -    [('selec-file_modification', forms.FileFormSelection), -     ('general-file_modification', forms.FileFormGeneralRO), -     ('towns-file_modification', TownFormset), -     ('parcels-file_modification', forms.ParcelFormset), -     ('preventive-file_modification', forms.FileFormPreventive), -     ('research-file_modification', forms.FileFormResearch), -     ('final-file_modification', forms.FinalForm)], +    [ +        ("selec-file_modification", forms.FileFormSelection), +        ("general-file_modification", forms.FileFormGeneralRO), +        ("towns-file_modification", TownFormset), +        ("parcels-file_modification", forms.ParcelFormset), +        ("preventive-file_modification", forms.FileFormPreventive), +        ("research-file_modification", forms.FileFormResearch), +        ("final-file_modification", forms.FinalForm), +    ],      label=_("File modification"),      condition_dict={ -        'preventive-file_modification': -            is_preventive('general-file_modification', -                          models.FileType, type_key='file_type'), -        'research-file_modification': -            is_not_preventive('general-file_modification', -                              models.FileType, type_key='file_type'), +        "preventive-file_modification": is_preventive( +            "general-file_modification", models.FileType, type_key="file_type" +        ), +        "research-file_modification": is_not_preventive( +            "general-file_modification", models.FileType, type_key="file_type" +        ),      }, -    url_name='file_modification',) +    url_name="file_modification", +)  def file_modify(request, pk): -    if not wizard_is_available(file_modification_wizard, request, -                               models.File, pk): +    if not wizard_is_available(file_modification_wizard, request, models.File, pk):          return HttpResponseRedirect("/")      FileModificationWizard.session_set_value( -        request, 'selec-file_modification', 'pk', pk, reset=True) -    return redirect(reverse('file_modification', -                    kwargs={'step': 'general-file_modification'})) +        request, "selec-file_modification", "pk", pk, reset=True +    ) +    return redirect( +        reverse("file_modification", kwargs={"step": "general-file_modification"}) +    ) +  file_closing_wizard = wizards.FileClosingWizard.as_view( -    [('selec-file_closing', forms.FileFormSelection), -     ('date-file_closing', ClosingDateFormSelection), -     ('final-file_closing', forms.FinalFileClosingForm)], -    label=_("File closing"), url_name='file_closing',) +    [ +        ("selec-file_closing", forms.FileFormSelection), +        ("date-file_closing", ClosingDateFormSelection), +        ("final-file_closing", forms.FinalFileClosingForm), +    ], +    label=_("File closing"), +    url_name="file_closing", +)  file_deletion_wizard = wizards.FileDeletionWizard.as_view( -    [('selec-file_deletion', forms.FileFormMultiSelection), -     ('final-file_deletion', forms.FinalFileDeleteForm)], +    [ +        ("selec-file_deletion", forms.FileFormMultiSelection), +        ("final-file_deletion", forms.FinalFileDeleteForm), +    ],      label=_("File deletion"), -    url_name='file_deletion',) +    url_name="file_deletion", +)  def file_delete(request, pk): @@ -178,74 +213,100 @@ def file_delete(request, pk):          return HttpResponseRedirect("/")      wizards.FileDeletionWizard.session_set_value( -        request, 'selec-file_deletion', 'pks', pk, reset=True) -    return redirect(reverse('file_deletion', -                            kwargs={'step': 'final-file_deletion'})) - -file_administrativeactfile_search_wizard = \ -    SearchWizard.as_view([ -        ('selec-file_administrativeactfile_search', -        forms.AdministrativeActFileFormSelection)], -        label=_("File: search administrative act"), -        url_name='file_administrativeactfile_search',) - -file_administrativeactfile_wizard = \ -    wizards.FileAdministrativeActWizard.as_view([ -        ('selec-file_administrativeactfile', forms.FileFormSelection), -        ('administrativeact-file_administrativeactfile', -         forms.AdministrativeActFileForm), -        ('final-file_administrativeactfile', forms.FinalForm)], -        label=_("File: new administrative act"), -        url_name='file_administrativeactfile',) - -file_administrativeactfile_modification_wizard = \ -    wizards.FileEditAdministrativeActWizard.as_view([ -        ('selec-file_administrativeactfile_modification', -         forms.AdministrativeActFileModifyFormSelection), -        ('administrativeact-file_administrativeactfile_modification', -         forms.AdministrativeActFileModifForm), -        ('final-file_administrativeactfile_modification', forms.FinalForm)], +        request, "selec-file_deletion", "pks", pk, reset=True +    ) +    return redirect(reverse("file_deletion", kwargs={"step": "final-file_deletion"})) + + +file_administrativeactfile_search_wizard = SearchWizard.as_view( +    [ +        ( +            "selec-file_administrativeactfile_search", +            forms.AdministrativeActFileFormSelection, +        ) +    ], +    label=_("File: search administrative act"), +    url_name="file_administrativeactfile_search", +) + +file_administrativeactfile_wizard = wizards.FileAdministrativeActWizard.as_view( +    [ +        ("selec-file_administrativeactfile", forms.FileFormSelection), +        ( +            "administrativeact-file_administrativeactfile", +            forms.AdministrativeActFileForm, +        ), +        ("final-file_administrativeactfile", forms.FinalForm), +    ], +    label=_("File: new administrative act"), +    url_name="file_administrativeactfile", +) + +file_administrativeactfile_modification_wizard = ( +    wizards.FileEditAdministrativeActWizard.as_view( +        [ +            ( +                "selec-file_administrativeactfile_modification", +                forms.AdministrativeActFileModifyFormSelection, +            ), +            ( +                "administrativeact-file_administrativeactfile_modification", +                forms.AdministrativeActFileModifForm, +            ), +            ("final-file_administrativeactfile_modification", forms.FinalForm), +        ],          label=_("File: administrative act modification"), -        url_name='file_administrativeactfile_modification',) +        url_name="file_administrativeactfile_modification", +    ) +)  def file_administrativeactfile_modify(request, pk): -    if not wizard_is_available(file_administrativeactfile_modification_wizard, -                               request, AdministrativeAct, pk): +    if not wizard_is_available( +        file_administrativeactfile_modification_wizard, request, AdministrativeAct, pk +    ):          return HttpResponseRedirect("/")      wizards.FileEditAdministrativeActWizard.session_set_value( -        request, 'selec-file_administrativeactfile_modification', -        'pk', pk, reset=True) +        request, "selec-file_administrativeactfile_modification", "pk", pk, reset=True +    )      return redirect(          reverse( -            'file_administrativeactfile_modification', +            "file_administrativeactfile_modification",              kwargs={ -                'step': -                'administrativeact-file_administrativeactfile_modification' -            })) +                "step": "administrativeact-file_administrativeactfile_modification" +            }, +        ) +    ) -file_administrativeactfile_deletion_wizard = \ -    AdministrativeActDeletionWizard.as_view([ -        ('selec-file_administrativeactfile_deletion', -         forms.AdministrativeActFileFormSelection), -        ('final-file_administrativeactfile_deletion', -         FinalAdministrativeActDeleteForm)], -        label=_("File: administrative act deletion"), -        url_name='file_administrativeactfile_deletion',) +file_administrativeactfile_deletion_wizard = AdministrativeActDeletionWizard.as_view( +    [ +        ( +            "selec-file_administrativeactfile_deletion", +            forms.AdministrativeActFileFormSelection, +        ), +        ("final-file_administrativeactfile_deletion", FinalAdministrativeActDeleteForm), +    ], +    label=_("File: administrative act deletion"), +    url_name="file_administrativeactfile_deletion", +)  def file_administrativeact_delete(request, pk): -    if not wizard_is_available(file_administrativeactfile_deletion_wizard, -                               request, AdministrativeAct, pk): +    if not wizard_is_available( +        file_administrativeactfile_deletion_wizard, request, AdministrativeAct, pk +    ):          return HttpResponseRedirect("/")      AdministrativeActDeletionWizard.session_set_value( -        request, 'selec-file_administrativeactfile_deletion', 'pk', pk, -        reset=True) +        request, "selec-file_administrativeactfile_deletion", "pk", pk, reset=True +    )      return redirect( -        reverse('file_administrativeactfile_deletion', -                kwargs={'step': 'final-file_administrativeactfile_deletion'})) +        reverse( +            "file_administrativeactfile_deletion", +            kwargs={"step": "final-file_administrativeactfile_deletion"}, +        ) +    )  def file_adminact_add(request, pk, current_right=None): @@ -255,10 +316,14 @@ def file_adminact_add(request, pk, current_right=None):          raise Http404()      file_administrativeactfile_wizard(request)      wizards.FileAdministrativeActWizard.session_set_value( -        request, 'selec-file_administrativeactfile', 'pk', pk, reset=True) -    return redirect(reverse( -        'file_administrativeactfile', -        kwargs={'step': 'administrativeact-file_administrativeactfile'})) +        request, "selec-file_administrativeactfile", "pk", pk, reset=True +    ) +    return redirect( +        reverse( +            "file_administrativeactfile", +            kwargs={"step": "administrativeact-file_administrativeactfile"}, +        ) +    )  def file_add_operation(request, pk, current_right=None): @@ -268,22 +333,24 @@ def file_add_operation(request, pk, current_right=None):          raise Http404()      operation_creation_wizard(request)      OperationWizard.session_set_value( -        request, 'filechoice-operation_creation', 'associated_file', pk, -        reset=True) -    return redirect(reverse( -        'operation_creation', -        kwargs={'step': 'general-operation_creation'})) +        request, "filechoice-operation_creation", "associated_file", pk, reset=True +    ) +    return redirect( +        reverse("operation_creation", kwargs={"step": "general-operation_creation"}) +    )  def reset_wizards(request):      for wizard_class, url_name in ( -            (FileWizard, 'file_creation'), -            (FileModificationWizard, 'file_modification'), -            (FileClosingWizard, 'file_modification'), -            (FileDeletionWizard, 'file_deletion'), -            (FileAdministrativeActWizard, 'file_administrativeactfile'), -            (FileEditAdministrativeActWizard, -             'file_administrativeactfile_modification_wizard'), -            (AdministrativeActDeletionWizard, -             'file_administrativeactfile_deletion_wizard'),): +        (FileWizard, "file_creation"), +        (FileModificationWizard, "file_modification"), +        (FileClosingWizard, "file_modification"), +        (FileDeletionWizard, "file_deletion"), +        (FileAdministrativeActWizard, "file_administrativeactfile"), +        ( +            FileEditAdministrativeActWizard, +            "file_administrativeactfile_modification_wizard", +        ), +        (AdministrativeActDeletionWizard, "file_administrativeactfile_deletion_wizard"), +    ):          wizard_class.session_reset(request, url_name) diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py index c259effbe..1538a984a 100644 --- a/archaeological_files/wizards.py +++ b/archaeological_files/wizards.py @@ -23,10 +23,11 @@ from django.db.models import Max  from ishtar_common.utils import ugettext_lazy as _  from ishtar_common.forms import reverse_lazy -from ishtar_common.wizards import ClosingWizard, SearchWizard, \ -    MultipleDeletionWizard -from archaeological_operations.wizards import OperationWizard,\ -    OperationAdministrativeActWizard +from ishtar_common.wizards import ClosingWizard, SearchWizard, MultipleDeletionWizard +from archaeological_operations.wizards import ( +    OperationWizard, +    OperationAdministrativeActWizard, +)  from archaeological_operations.models import AdministrativeAct, Parcel  from . import models @@ -37,26 +38,26 @@ class FileSearch(SearchWizard):  class FileWizard(OperationWizard):      model = models.File -    object_parcel_type = 'associated_file' -    parcel_step_key = 'parcels-' -    town_step_keys = ['towns-'] -    wizard_done_window = reverse_lazy('show-file') +    object_parcel_type = "associated_file" +    parcel_step_key = "parcels-" +    town_step_keys = ["towns-"] +    wizard_done_window = reverse_lazy("show-file")      redirect_url = "file_modification"      def get_extra_model(self, dct, m2m, form_list):          dct = super(FileWizard, self).get_extra_model(dct, m2m, form_list) -        if not dct.get('numeric_reference'): -            current_ref = models.File.objects.filter(year=dct['year'])\ -                .aggregate(Max('numeric_reference'))["numeric_reference__max"] -            dct['numeric_reference'] = current_ref and current_ref + 1 or 1 +        if not dct.get("numeric_reference"): +            current_ref = models.File.objects.filter(year=dct["year"]).aggregate( +                Max("numeric_reference") +            )["numeric_reference__max"] +            dct["numeric_reference"] = current_ref and current_ref + 1 or 1          return dct      def done(self, form_list, **kwargs):          """          Save parcels and make numeric_reference unique          """ -        r = super(FileWizard, self).done(form_list, return_object=True, -                                         **kwargs) +        r = super(FileWizard, self).done(form_list, return_object=True, **kwargs)          if type(r) not in (list, tuple) or len(r) != 2:              return r          obj, res = r @@ -64,9 +65,13 @@ class FileWizard(OperationWizard):          if not self.modification:              numeric_reference = obj.numeric_reference              changed = False -            while obj.__class__.objects.filter( -                    numeric_reference=numeric_reference, -                    year=obj.year).exclude(pk=obj.pk).count(): +            while ( +                obj.__class__.objects.filter( +                    numeric_reference=numeric_reference, year=obj.year +                ) +                .exclude(pk=obj.pk) +                .count() +            ):                  numeric_reference += 1                  changed = True              if changed: @@ -74,33 +79,35 @@ class FileWizard(OperationWizard):                  obj.save()          obj.parcels.clear()          for form in form_list: -            if not hasattr(form, 'prefix') \ -               or not form.prefix.startswith(self.parcel_step_key) \ -               or not hasattr(form, 'forms'): +            if ( +                not hasattr(form, "prefix") +                or not form.prefix.startswith(self.parcel_step_key) +                or not hasattr(form, "forms") +            ):                  continue              for frm in form.forms:                  if not frm.is_valid():                      continue                  dct = frm.cleaned_data.copy() -                if 'parcel' in dct: +                if "parcel" in dct:                      try: -                        parcel = Parcel.objects.get(pk=dct['parcel']) +                        parcel = Parcel.objects.get(pk=dct["parcel"])                          setattr(parcel, self.object_parcel_type, obj)                          parcel.save()                      except (ValueError, ObjectDoesNotExist):                          continue                      continue                  try: -                    dct['town'] = models.Town.objects.get(pk=int(dct['town'])) +                    dct["town"] = models.Town.objects.get(pk=int(dct["town"]))                  except (ValueError, ObjectDoesNotExist, KeyError):                      continue -                dct['associated_file'], dct['operation'] = None, None +                dct["associated_file"], dct["operation"] = None, None                  dct[self.object_parcel_type] = obj -                if 'DELETE' in dct: -                    dct.pop('DELETE') +                if "DELETE" in dct: +                    dct.pop("DELETE")                  parcel = Parcel.objects.filter(**dct).count()                  if not parcel: -                    dct['history_modifier'] = self.request.user +                    dct["history_modifier"] = self.request.user                      parcel = Parcel(**dct)                      parcel.save()          return res @@ -110,18 +117,30 @@ class FileModificationWizard(FileWizard):      modification = True -FILE_FIELDS = ['year', 'numeric_reference', 'internal_reference', -               'file_type', 'in_charge', 'general_contractor', 'creation_date', -               'reception_date', 'total_surface', 'total_developed_surface', -               'address', 'address_complement', 'postal_code', 'comment'] +FILE_FIELDS = [ +    "year", +    "numeric_reference", +    "internal_reference", +    "file_type", +    "in_charge", +    "general_contractor", +    "creation_date", +    "reception_date", +    "total_surface", +    "total_developed_surface", +    "address", +    "address_complement", +    "postal_code", +    "comment", +]  class FileClosingWizard(ClosingWizard):      model = models.File      fields = FILE_FIELDS -    if settings.COUNTRY == 'fr': -        fields += ['saisine_type', 'permit_reference'] -    fields += ['towns'] +    if settings.COUNTRY == "fr": +        fields += ["saisine_type", "permit_reference"] +    fields += ["towns"]  class FileDeletionWizard(MultipleDeletionWizard, FileClosingWizard): @@ -129,24 +148,28 @@ class FileDeletionWizard(MultipleDeletionWizard, FileClosingWizard):      redirect_url = "file_deletion"      fields = FILE_FIELDS      wizard_templates = { -        'final-file_deletion': 'ishtar/wizard/wizard_file_deletion.html'} +        "final-file_deletion": "ishtar/wizard/wizard_file_deletion.html" +    }  class FileAdministrativeActWizard(OperationAdministrativeActWizard):      model = models.File -    current_obj_slug = 'administrativeactfile' -    ref_object_key = 'associated_file' +    current_obj_slug = "administrativeactfile" +    ref_object_key = "associated_file"      def get_reminder(self): -        form_key = 'selec-' + self.url_name -        if self.url_name.endswith('_administrativeactfile'): +        form_key = "selec-" + self.url_name +        if self.url_name.endswith("_administrativeactfile"):              # modification and deletion are suffixed with '_modification'              # and '_deletion' so it is creation              file_id = self.session_get_value(form_key, "pk")              try:                  return ( -                    (_("Archaeological file"), -                     str(models.File.objects.get(pk=file_id))),) +                    ( +                        _("Archaeological file"), +                        str(models.File.objects.get(pk=file_id)), +                    ), +                )              except models.File.DoesNotExist:                  return          else: @@ -155,8 +178,7 @@ class FileAdministrativeActWizard(OperationAdministrativeActWizard):                  admin = AdministrativeAct.objects.get(pk=admin_id)                  if not admin.associated_file:                      return -                return ((_("Archaeological file"), -                         str(admin.associated_file)),) +                return ((_("Archaeological file"), str(admin.associated_file)),)              except AdministrativeAct.DoesNotExist:                  return | 
