#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2010-2016 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. """ Files forms definitions """ import datetime from django import forms from django.conf import settings from django.core import validators from django.forms.formsets import formset_factory 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_common import Department 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_common import get_town_field from archaeological_operations.forms import ( AdministrativeActForm, AdministrativeActOpeFormSelection, SLICING, AdministrativeActModifForm, ParcelForm, ParcelFormSet, ) from ishtar_common import widgets from bootstrap_datepicker.widgets import DatePicker class FileSelect(DocumentItemSelect): _model = models.File form_admin_name = _("File - 001 - Search") form_slug = "file-001-search" search_vector = forms.CharField( 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")) towns = get_town_field() parcel = forms.CharField(label=_("Parcel")) if settings.ISHTAR_DPTS: towns__numero_insee__startswith = forms.ChoiceField( 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")) 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)], ) 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)], ) 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)], ) history_creator = forms.IntegerField( label=_("Created by"), widget=widgets.JQueryAutoComplete( 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)], ) TYPES = [ 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" if settings.ISHTAR_DPTS and k in self.fields: 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} pk = forms.IntegerField( 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)], ) class FileFormMultiSelection(LockForm, MultiSearchForm): form_label = _("Archaeological file search") associated_models = {"pks": models.File} pk = forms.CharField( label="", required=False, widget=widgets.DataTable( reverse_lazy("get-file"), FileSelect, models.File, multiple_select=True, source_full=reverse_lazy("get-file-full"), ), validators=[valid_ids(models.File)], ) 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) date_source = forms.ChoiceField( 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) def __init__(self, *args, **kwargs): 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() def get_show_detail(self): 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"] return date_source def get_filter(self): 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"] return fltr class FileFormGeneral(ManageOldType): form_label = _("General") 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), ], ) numeric_reference = forms.IntegerField( label=_("Numeric reference"), widget=forms.HiddenInput, required=False ) internal_reference = forms.CharField( 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 ) 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) total_surface = forms.FloatField( required=False, widget=widgets.AreaWidget, label=_("Total surface (m2)"), 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 ) 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 += _("
(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}) ) numeric_reference = forms.IntegerField( 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) if numeric_reference and q.count(): raise forms.ValidationError(_("Another file with this numeric id exists.")) return cleaned_data 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" 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, } general_contractor = forms.IntegerField( label=_("General contractor"), widget=widgets.JQueryAutoComplete( reverse_lazy( "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)], ) 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"])], ), 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)], ) 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=[]) reception_date = forms.DateField( 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() 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, } department = widgets.Select2MultipleField( 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"])], ), 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, detail=True, modify=True, ), label=_("Scientist in charge"), ) requested_operation_type = forms.ChoiceField( label=_("Requested operation type"), choices=[] ) organization = forms.IntegerField( label=_("Lead organization"), widget=widgets.JQueryAutoComplete( reverse_lazy("autocomplete-organization"), associated_model=Organization, new=True, detail=True, modify=True, ), validators=[valid_id(Organization)], 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": mh_register = forms.NullBooleanField( 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) 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() class FinalFileClosingForm(FinalForm): confirm_msg = " " confirm_end_msg = _("Would you like to close this archaeological file?") class FinalFileDeleteForm(FinalForm): confirm_msg = " " confirm_end_msg = _("Would you like to delete this archaeological file ?") class AdministrativeActFileModifySelect(TableSelect): _model = AdministrativeAct search_vector = forms.CharField( 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) act_type = forms.ChoiceField(label=_("Act type"), choices=[]) 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=[] ) 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" if settings.ISHTAR_DPTS and k in self.fields: 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", ), ) 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) 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) signature_date_before = forms.DateField( 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) 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)], ) 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)], ) associated_file__numeric_reference = forms.IntegerField( 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") ) 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)], ) associated_file__permit_reference = forms.CharField( 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)], ) history_modifier = forms.IntegerField( label=_("Modified by"), widget=widgets.JQueryAutoComplete( 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 k in self.fields and settings.ISHTAR_DPTS: self.fields[k].choices = [("", "--")] + list(settings.ISHTAR_DPTS) class AdministrativeActFileFormSelection(AdministrativeActOpeFormSelection): SEARCH_AND_SELECT = True pk = forms.IntegerField( label="", required=False, widget=widgets.DataTable( reverse_lazy("get-administrativeactfile"), AdministrativeActFileSelect, AdministrativeAct, table_cols="TABLE_COLS_FILE", ), validators=[valid_id(AdministrativeAct)], ) class AdministrativeActFileModifyFormSelection(AdministrativeActOpeFormSelection): SEARCH_AND_SELECT = True pk = forms.IntegerField( label="", required=False, widget=widgets.DataTable( reverse_lazy("get-administrativeactfile"), AdministrativeActFileModifySelect, AdministrativeAct, table_cols="TABLE_COLS_FILE", ), validators=[valid_id(AdministrativeAct)], ) class AdministrativeActFileForm(AdministrativeActForm): form_admin_name = _("Archaeological file - Administrative act - General") form_slug = "file-adminact-general" act_type = forms.ChoiceField(label=_("Act type"), choices=[]) TYPES = [ FieldType("act_type", ActType, extra_args={"dct": {"intented_to": "F"}}), ] class AdministrativeActFileModifForm( AdministrativeActModifForm, AdministrativeActFileForm ): pk = forms.IntegerField(required=False, widget=forms.HiddenInput) index = forms.IntegerField(label=_("Index"), required=False)