#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2010-2012 É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.core.exceptions import ObjectDoesNotExist from django.db.models import Max from django.shortcuts import render_to_response from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from ishtar_common.models import Town import models from ishtar_common.views import Wizard from ishtar_common.forms import FinalForm, FormSet, ClosingWizard, \ ClosingDateFormSelection, SearchWizard, formset_factory, get_now, \ reverse_lazy from ishtar_common.forms_common import TownFormset, ParcelFormSet, \ get_town_field, get_person_field from archaeological_operations.forms import OperationAdministrativeActWizard, \ AdministrativeActOpeForm, AdministrativeActOpeFormSelection, \ AdministrativeActDeletionWizard, FinalAdministrativeActDeleteForm, \ is_preventive from ishtar_common import widgets class FileWizard(Wizard): model = models.File object_parcel_type = 'associated_file' def get_form(self, request, storage, step=None, data=None, files=None): """ Manage towns """ if data: data = data.copy() else: data = {} # manage the dynamic choice of towns if not step: step = self.determine_step(request, storage) form = self.get_form_list(request, storage)[step] town_form_key = 'towns-' + self.url_name if step.startswith('parcels-') and hasattr(form, 'management_form') \ and self.session_has_key(request, storage, town_form_key): towns = [] qdict = request.session[storage.prefix]['step_data'][town_form_key] for k in qdict.keys(): if k.endswith("town") and qdict[k]: try: town = Town.objects.get(pk=int(qdict[k])) towns.append((town.pk, unicode(town))) except (ObjectDoesNotExist, ValueError): pass data['TOWNS'] = sorted(towns, key=lambda x:x[1]) form = super(FileWizard, self).get_form(request, storage, step, data, files) return form def get_extra_model(self, dct, request, storage, form_list): dct = super(FileWizard, self).get_extra_model(dct, request, storage, form_list) if not dct['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, request, storage, form_list, **kwargs): ''' Save parcels ''' r = super(FileWizard, self).done(request, storage, form_list, return_object=True, **kwargs) if type(r) not in (list, tuple) or len(r) != 2: return r obj, res = r obj.parcels.clear() for form in form_list: if not hasattr(form, 'prefix') \ or not form.prefix.startswith('parcels-') \ 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: try: parcel = models.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'])) except (ValueError, ObjectDoesNotExist): continue dct['associated_file'], dct['operation'] = None, None dct[self.object_parcel_type] = obj if 'DELETE' in dct: dct.pop('DELETE') parcel = models.Parcel.objects.filter(**dct).count() if not parcel: dct['history_modifier'] = request.user parcel = models.Parcel(**dct) parcel.save() return res class FileSelect(forms.Form): towns = get_town_field() in_charge = get_person_field(label=_(u"Person in charge"), person_type='sra_agent') file_type = forms.ChoiceField(label=_("File type"), choices=models.FileType.get_types()) saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[]) year = forms.IntegerField(label=_("Year")) def __init__(self, *args, **kwargs): super(FileSelect, self).__init__(*args, **kwargs) self.fields['saisine_type'].choices = models.SaisineType.get_types() self.fields['saisine_type'].help_text = models.SaisineType.get_help() class FileFormSelection(forms.Form): form_label = _("Archaeological file search") associated_models = {'pk':models.File} currents = {'pk':models.File} pk = forms.IntegerField(label="", required=False, widget=widgets.JQueryJqGrid(reverse_lazy('get-file'), FileSelect(), models.File, source_full=reverse_lazy('get-file-full')), validators=[models.valid_id(models.File)]) def clean(self): cleaned_data = self.cleaned_data if 'pk' not in cleaned_data or not cleaned_data['pk']: raise forms.ValidationError(_(u"You should select a file.")) return cleaned_data class FileFormGeneral(forms.Form): form_label = _("General") associated_models = {'in_charge':models.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=[models.PersonType.objects.get(txt_idx='sra_agent').pk]), associated_model=models.Person, new=True), validators=[models.valid_id(models.Person)]) year = forms.IntegerField(label=_("Year"), initial=lambda:datetime.datetime.now().year, validators=[validators.MinValueValidator(1900), validators.MaxValueValidator(2100)]) numeric_reference = forms.IntegerField(label=_("Numeric reference"), widget=forms.HiddenInput, required=False) internal_reference = forms.CharField(label=_(u"Internal reference"), max_length=60, validators=[models.is_unique(models.File, 'internal_reference')]) creation_date = forms.DateField(label=_(u"Creation date"), initial=get_now, widget=widgets.JQueryDate) file_type = forms.ChoiceField(label=_("File type"), choices=models.FileType.get_types()) related_file = forms.IntegerField(label=_("Related file"), required=False, widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'), associated_model=models.File), validators=[models.valid_id(models.File)]) comment = forms.CharField(label=_(u"Comment"), widget=forms.Textarea, required=False) class FileFormGeneralRO(FileFormGeneral): year = forms.IntegerField(label=_(u"Year"), widget=forms.TextInput(attrs={'readonly':True})) numeric_reference = forms.IntegerField(label=_(u"Numeric reference"), widget=forms.TextInput(attrs={'readonly':True})) internal_reference = forms.CharField(label=_(u"Internal reference"), widget=forms.TextInput(attrs={'readonly':True},)) class FileFormAddress(forms.Form): form_label = _(u"Address") associated_models = {'town':models.Town} total_surface = forms.IntegerField(required=False, widget=widgets.AreaWidget, label=_(u"Total surface (m²)"), validators=[validators.MinValueValidator(0), validators.MaxValueValidator(999999999)]) address = forms.CharField(label=_(u"Main address"), widget=forms.Textarea) address_complement = forms.CharField(label=_(u"Main address - complement"), required=False) postal_code = forms.CharField(label=_(u"Main address - postal code"), max_length=10) class FileFormPreventive(forms.Form): form_label = _(u"Preventive informations") associated_models = {'general_contractor':models.Person, 'saisine_type':models.SaisineType, 'permit_type':models.PermitType, 'town_planning_service':models.Organization} general_contractor = forms.IntegerField(label=_(u"General contractor"), widget=widgets.JQueryAutoComplete( reverse_lazy('autocomplete-person', args=[models.PersonType.objects.get(txt_idx='general_contractor').pk]), associated_model=models.Person, new=True), validators=[models.valid_id(models.Person)]) town_planning_service = forms.IntegerField(required=False, label=_(u"Town planning service"), widget=widgets.JQueryAutoComplete( reverse_lazy('autocomplete-organization', args=[models.OrganizationType.objects.get(txt_idx='planning_service').pk]), associated_model=models.Organization, new=True), validators=[models.valid_id(models.Organization)]) permit_type = forms.ChoiceField(label=_(u"Permit type"), required=False, choices=models.PermitType.get_types()) permit_reference = forms.CharField(label=_(u"Permit reference"), required=False, validators=[validators.MaxLengthValidator(60)]) total_developed_surface = forms.IntegerField(widget=widgets.AreaWidget, label=_(u"Total developed surface (m²)"), required=False, validators=[validators.MinValueValidator(0), validators.MaxValueValidator(999999999)]) if settings.COUNTRY == 'fr': saisine_type = forms.ChoiceField(label=_(u"Saisine type"), choices=[]) reception_date = forms.DateField(label=_(u"Reception date"), initial=get_now, widget=widgets.JQueryDate) def __init__(self, *args, **kwargs): super(FileFormPreventive, self).__init__(*args, **kwargs) self.fields['saisine_type'].choices = models.SaisineType.get_types() self.fields['saisine_type'].help_text = models.SaisineType.get_help() file_search_wizard = SearchWizard([('general-file_search', FileFormSelection)], url_name='file_search',) file_creation_wizard = FileWizard([ ('general-file_creation', FileFormGeneral), ('address-file_creation', FileFormAddress), ('towns-file_creation', TownFormset), ('parcels-file_creation', ParcelFormSet), ('preventive-file_creation', FileFormPreventive), ('final-file_creation', FinalForm)], condition_list={ 'preventive-file_creation':is_preventive('general-file_creation', models.FileType, type_key='file_type') }, url_name='file_creation',) class FileModificationWizard(FileWizard): modification = True file_modification_wizard = FileModificationWizard([ ('selec-file_modification', FileFormSelection), ('general-file_modification', FileFormGeneralRO), ('adress-file_modification', FileFormAddress), ('towns-file_modification', TownFormset), ('parcels-file_modification', ParcelFormSet), ('preventive-file_modification', FileFormPreventive), ('final-file_modification', FinalForm)], condition_list={ 'preventive-file_modification':is_preventive('general-file_modification', models.FileType, type_key='file_type') }, url_name='file_modification',) class FileClosingWizard(ClosingWizard): model = models.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'] if settings.COUNTRY == 'fr': fields += ['saisine_type', 'reference_number'] fields += ['towns'] class FinalFileClosingForm(FinalForm): confirm_msg = " " confirm_end_msg = _(u"Would you like to close this archaeological file?") file_closing_wizard = FileClosingWizard([ ('selec-file_closing', FileFormSelection), ('date-file_closing', ClosingDateFormSelection), ('final-file_closing', FinalFileClosingForm)], url_name='file_closing',) class FileDeletionWizard(FileClosingWizard): def get_formated_datas(self, forms): datas = super(FileDeletionWizard, self).get_formated_datas(forms) datas.append((_("Associated operations"), [])) for operation in models.Operation.objects.filter( associated_file=self.current_obj).all(): if operation.end_date: datas[-1][1].append(('', unicode(operation))) return datas def done(self, request, storage, form_list, **kwargs): obj = self.get_current_object(request, storage) for operation in models.Operation.objects.filter( associated_file=obj).all(): operation.delete() obj.delete() return render_to_response('wizard_done.html', {}, context_instance=RequestContext(request)) class FinalFileDeleteForm(FinalForm): confirm_msg = " " confirm_end_msg = _(u"Would you like to delete this archaelogical file ?") file_deletion_wizard = FileDeletionWizard([ ('selec-file_deletion', FileFormSelection), ('final-file_deletion', FinalFileDeleteForm)], url_name='file_deletion',) class FileAdministrativeActWizard(OperationAdministrativeActWizard): model = models.File class FileEditAdministrativeActWizard(FileAdministrativeActWizard): model = models.AdministrativeAct edit = True def get_associated_item(self, request, storage, dct): return self.get_current_object(request, storage).associated_file class AdministrativeActFileSelect(forms.Form): associated_file__towns = get_town_field() act_type = forms.ChoiceField(label=_("Act type"), choices=[]) def __init__(self, *args, **kwargs): super(AdministrativeActFileSelect, self).__init__(*args, **kwargs) self.fields['act_type'].choices = models.ActType.get_types( dct={'intented_to':'F'}) self.fields['act_type'].help_text = models.ActType.get_help( dct={'intented_to':'F'}) class AdministrativeActFileFormSelection(AdministrativeActOpeFormSelection): pk = forms.IntegerField(label="", required=False, widget=widgets.JQueryJqGrid(reverse_lazy('get-administrativeactfile'), AdministrativeActFileSelect(), models.AdministrativeAct, table_cols='TABLE_COLS_FILE'), validators=[models.valid_id(models.AdministrativeAct)]) class AdministrativeActFileForm(AdministrativeActOpeForm): act_type = forms.ChoiceField(label=_(u"Act type"), choices=[]) def __init__(self, *args, **kwargs): super(AdministrativeActFileForm, self).__init__(*args, **kwargs) self.fields['act_type'].choices = models.ActType.get_types( dct={'intented_to':'F'}) self.fields['act_type'].help_text = models.ActType.get_help( dct={'intented_to':'F'}) file_administrativeactfile_wizard = FileAdministrativeActWizard([ ('selec-file_administrativeactfile', FileFormSelection), ('administrativeact-file_administrativeactfile', AdministrativeActFileForm), ('final-file_administrativeactfile', FinalForm)], url_name='file_administrativeactfile',) file_administrativeactfile_modification_wizard = FileEditAdministrativeActWizard([ ('selec-file_administrativeactfile_modification', AdministrativeActFileFormSelection), ('administrativeact-file_administrativeactfile_modification', AdministrativeActFileForm), ('final-file_administrativeactfile_modification', FinalForm)], url_name='file_administrativeactfile_modification',) file_administrativeactfile_deletion_wizard = AdministrativeActDeletionWizard([ ('selec-file_administrativeactfile_deletion', AdministrativeActFileFormSelection), ('final-file_administrativeactfile_deletion', FinalAdministrativeActDeleteForm)], url_name='file_administrativeactfile_deletion',)