diff options
| -rw-r--r-- | archaeological_files/forms.py | 16 | ||||
| -rw-r--r-- | archaeological_files/models.py | 2 | ||||
| -rw-r--r-- | archaeological_files/wizards.py | 2 | ||||
| -rw-r--r-- | archaeological_operations/forms.py | 66 | 
4 files changed, 83 insertions, 3 deletions
| diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index ac3c9fe83..b03877a3d 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -228,7 +228,21 @@ 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})) +                        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( +                     _(u"Another file with this numeric id exists.")) +        return cleaned_data  RESPONSIBLE_PLANNING_SERVICE, created = PersonType.objects.get_or_create(                                 txt_idx='responsible_planning_service') diff --git a/archaeological_files/models.py b/archaeological_files/models.py index 2b0b299ec..4c9705641 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- -# Copyright (C) 2012-2014 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2012-2015 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet>  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU Affero General Public License as diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py index 3ccd6e3d9..26dc90f21 100644 --- a/archaeological_files/wizards.py +++ b/archaeological_files/wizards.py @@ -78,7 +78,7 @@ class FileWizard(OperationWizard):      def get_extra_model(self, dct, form_list):          dct = super(FileWizard, self).get_extra_model(dct, form_list) -        if not dct['numeric_reference']: +        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 diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index d0e4be0d3..0bc759b9c 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -36,6 +36,8 @@ from django.utils.safestring import mark_safe  from ishtar_common.models import valid_id, PersonType, Person, Town, \                               DocumentTemplate, Organization, OrganizationType +from ishtar_common.wizards import MultiValueDict +  FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS  if FILES_AVAILABLE: @@ -120,6 +122,8 @@ class ParcelFormSet(FormSet):      SELECTION_FORM = ParcelSelectionForm      def __init__(self, *args, **kwargs): +        if 'data' in kwargs and kwargs['data']: +            kwargs['data'] = self.rearrange_parcels(kwargs['data'])          super(FormSet, self).__init__(*args, **kwargs)          self.extra_form = None          if self.forms[0].__class__.__name__ == 'ParcelForm': @@ -133,6 +137,68 @@ class ParcelFormSet(FormSet):              if town_choices:                  self.selection_form.fields['_town'].choices = town_choices +    def rearrange_parcels(self, parcels): +        """ +        Simple database ordering is not possible as a numeric ordering of parcel +        number have to be made but with parcel number not strictly numeric +        Very complicated for a simple thing :( +        """ +        prefix, ordering_keys, values = '', {}, {} +        new_values = MultiValueDict() +        for k in parcels: +            value = parcels[k] +            splitted = k.split('-') +            if len(splitted) < 4: +                new_values[k] = value +                continue +            if not prefix: +                prefix = "-".join(splitted[:-2]) +            field = splitted[-1] +            number = splitted[-2] + +            if number not in values: +                values[number] = {} +            values[number][field] = value + +            if number not in ordering_keys: +                ordering_keys[number] = ['', '', '', ''] +            if field == 'town': +                ordering_keys[number][0] = value +            if field == 'year': +                ordering_keys[number][1] = value +            if field == 'section': +                ordering_keys[number][2] = value +            if field == 'parcel_number': +                ordering_keys[number][3] = value + +        reverse_ordering_keys = {} +        for number in ordering_keys: +            reverse_ordering_keys[tuple(ordering_keys[number])] = number + +        for new_idx, keys in enumerate(sorted(reverse_ordering_keys.keys(), +                                         key=self._parcel_sorting)): +            number = reverse_ordering_keys[keys] +            prefx = '%s-%d-' % (prefix, new_idx) +            for field in values[number]: +                new_key = prefx + field +                new_values[new_key] = values[number][field] +        return new_values + +    def _parcel_sorting(self, key): +        town, year, section, parcel = key +        # deal with parcel_number such as '34p' and convert to int +        parcel_number = '' +        for p in parcel: +            try: +                parcel_number += str(int(p)) +            except ValueError: +                break +        if not parcel_number: +            parcel_number = 0 +        else: +            parcel_number = int(parcel_number) +        return (town, year, section, parcel_number) +      def as_table(self):          # add dynamic widget          render = self.selection_form.as_table() | 
