#!/usr/bin/env python # -*- 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" extra_form_modals = ["person", "organization"] 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)