diff options
| author | Étienne Loks <etienne.loks@proxience.com> | 2013-04-04 22:43:13 +0000 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@proxience.com> | 2013-04-04 22:43:13 +0000 |
| commit | ee8c9ad6004ab35e409c7041a0eba214b45c36d7 (patch) | |
| tree | a2c624b1ce76c6d57a8a156766e4863710d8ae19 /archaeological_operations | |
| parent | 56aea239caffef95c481aac3b77a8d43e8d3ca35 (diff) | |
| parent | e51684c2adb656d3ef14e40e649e280a6c0bf1b8 (diff) | |
| download | Ishtar-ee8c9ad6004ab35e409c7041a0eba214b45c36d7.tar.bz2 Ishtar-ee8c9ad6004ab35e409c7041a0eba214b45c36d7.zip | |
Merge branch 'master' of lysithea.proxience.net:/home/proxience/git/ishtar
Diffstat (limited to 'archaeological_operations')
| -rw-r--r-- | archaeological_operations/forms.py | 70 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 22 | ||||
| -rw-r--r-- | archaeological_operations/templates/ishtar/sheet_operation.html | 183 | ||||
| -rw-r--r-- | archaeological_operations/templates/ishtar/sheet_operation_pdf.html | 18 | ||||
| -rw-r--r-- | archaeological_operations/templates/ishtar/sheet_operation_window.html | 3 | ||||
| -rw-r--r-- | archaeological_operations/urls.py | 6 | ||||
| -rw-r--r-- | archaeological_operations/views.py | 39 | ||||
| -rw-r--r-- | archaeological_operations/widgets.py | 43 | ||||
| -rw-r--r-- | archaeological_operations/wizards.py | 41 |
9 files changed, 403 insertions, 22 deletions
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index f5f0fea99..72834d8f0 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2013 É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 @@ -35,26 +35,37 @@ from django.utils.translation import ugettext_lazy as _ from ishtar_common.models import valid_id, PersonType, Person, Town from archaeological_files.models import File import models +from widgets import ParcelWidget from ishtar_common import widgets -from ishtar_common.forms import FinalForm, FormSet, ClosingDateFormSelection, \ - formset_factory, get_now, reverse_lazy, get_form_selection +from ishtar_common.forms import BaseFormSet, FinalForm, FormSet, \ + ClosingDateFormSelection, formset_factory, get_now, reverse_lazy, \ + get_form_selection, TableSelect from ishtar_common.forms_common import TownForm, TownFormSet, TownFormset, \ AuthorFormset, SourceForm, SourceSelect, \ SourceDeletionForm, get_town_field +class ParcelField(forms.MultiValueField): + def __init__(self, *args, **kwargs): + if 'widget' not in kwargs: + self.widget = ParcelWidget() + return super(ParcelField, self).__init__(*args, **kwargs) + + def compress(data_list): + return u"-".join(data_list) + class ParcelForm(forms.Form): form_label = _("Parcels") base_model = 'parcel' associated_models = {'parcel':models.Parcel, 'town':models.Town} town = forms.ChoiceField(label=_("Town"), choices=(), required=False, validators=[valid_id(models.Town)]) + year = forms.IntegerField(label=_("Year"), required=False, + validators=[validators.MinValueValidator(1900), + validators.MaxValueValidator(2100)]) section = forms.CharField(label=_(u"Section"), required=False, validators=[validators.MaxLengthValidator(4)]) parcel_number = forms.CharField(label=_(u"Parcel number"), required=False, validators=[validators.MaxLengthValidator(6)]) - year = forms.IntegerField(label=_("Year"), required=False, - validators=[validators.MinValueValidator(1900), - validators.MaxValueValidator(2100)]) def __init__(self, *args, **kwargs): towns = None if 'data' in kwargs and 'TOWNS' in kwargs['data']: @@ -74,9 +85,11 @@ class ParcelForm(forms.Form): """Check required fields""" if any(self.errors): return - if not self.cleaned_data or DELETION_FIELD_NAME in self.cleaned_data \ - and self.cleaned_data[DELETION_FIELD_NAME]: + if not self.cleaned_data or (DELETION_FIELD_NAME in self.cleaned_data \ + and self.cleaned_data[DELETION_FIELD_NAME]): return + if not self.cleaned_data.get('parcel_number'): + return {} for key in ('town', 'parcel_number', 'section'): if not key in self.cleaned_data or not self.cleaned_data[key]: raise forms.ValidationError(_(u"Town section and parcel number " @@ -84,23 +97,49 @@ class ParcelForm(forms.Form): return self.cleaned_data class ParcelFormSet(FormSet): + def add_fields(self, form, index): + super(FormSet, self).add_fields(form, index) + def clean(self): """Checks that no parcels are duplicated.""" - return self.check_duplicate(('town', 'parcel_number', 'year'), - _(u"There are identical parcels.")) + return self.check_duplicate(('town', 'section', + 'parcel_number', 'year'), + _(u"There are identical parcels.")) ParcelFormSet = formset_factory(ParcelForm, can_delete=True, formset=ParcelFormSet) ParcelFormSet.form_label = _(u"Parcels") -class OperationSelect(forms.Form): +class OperationSelect(TableSelect): common_name = forms.CharField(label=_(u"Name"), max_length=30) + if settings.COUNTRY == 'fr': + code_patriarche = forms.IntegerField( + widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \ + 'autocomplete-patriarche/'), + label="Code PATRIARCHE") towns = get_town_field() operation_type = forms.ChoiceField(label=_(u"Operation type"), choices=[]) + in_charge = forms.IntegerField( + widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person', + args=["_".join( + [unicode(PersonType.objects.get(txt_idx='head_scientist').pk), + unicode(PersonType.objects.get(txt_idx='sra_agent').pk)])]), + associated_model=Person, new=True), label=_(u"In charge")) remains = forms.ChoiceField(label=_(u"Remains"), choices=models.RemainType.get_types()) + periods = forms.ChoiceField(label=_(u"Periods"), + choices=models.Period.get_types()) year = forms.IntegerField(label=_("Year")) + start_before = forms.DateField(label=_(u"Started before"), + widget=widgets.JQueryDate) + start_after = forms.DateField(label=_(u"Started after"), + widget=widgets.JQueryDate) + end_before = forms.DateField(label=_(u"Ended before"), + widget=widgets.JQueryDate) + end_after = forms.DateField(label=_(u"Ended after"), + widget=widgets.JQueryDate) + parcel = ParcelField(label=_("Parcel (section/number)")) end_date = forms.NullBooleanField(label=_(u"Is open?")) def __init__(self, *args, **kwargs): @@ -108,6 +147,13 @@ class OperationSelect(forms.Form): self.fields['operation_type'].choices = models.OperationType.get_types() self.fields['operation_type'].help_text = models.OperationType.get_help() + def get_input_ids(self): + ids = super(OperationSelect, self).get_input_ids() + ids.pop(ids.index('parcel')) + ids.append('parcel_0') + ids.append('parcel_1') + return ids + class OperationFormSelection(forms.Form): form_label = _(u"Operation search") associated_models = {'pk':models.Operation} @@ -406,7 +452,7 @@ OperationSourceFormSelection = get_form_selection( # Administrative act management for operations # ################################################ -class AdministrativeActOpeSelect(forms.Form): +class AdministrativeActOpeSelect(TableSelect): operation__towns = get_town_field() act_type = forms.ChoiceField(label=_("Act type"), choices=[]) diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 399b536e2..02ec1a912 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2012-2013 É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 @@ -18,6 +18,7 @@ # See the file COPYING for details. import datetime +from itertools import groupby from django.conf import settings from django.contrib.gis.db import models @@ -137,6 +138,9 @@ class Operation(BaseHistorizedItem, OwnPerms): unicode(self.operation_code)))) return settings.JOINT.join(items) + def grouped_parcels(self): + return Parcel.grouped_parcels(list(self.parcels.all())) + @classmethod def get_available_operation_code(cls, year=None): if not year: @@ -163,6 +167,7 @@ class Operation(BaseHistorizedItem, OwnPerms): def year_index(self): if not self.operation_code: return "" + lbl = unicode(self.operation_code) lbl = u"%d-%s%s" % (self.year, (3-len(lbl))*"0", lbl) return lbl @@ -327,6 +332,21 @@ class Parcel(LightHistorizedItem): def __unicode__(self): return self.short_label() + @staticmethod + def grouped_parcels(parcels): + sortkeyfn = lambda s:(getattr(s, 'year'), getattr(s, 'town'), + getattr(s, 'section')) + parcels.sort(key=sortkeyfn) + grouped = [] + for keys, parcel_grp in groupby(parcels, key=sortkeyfn): + for idx, parcel in enumerate(parcel_grp): + if not idx: + grouped.append(parcel) + grouped[-1].parcel_numbers = [] + grouped[-1].parcel_numbers.append(parcel.parcel_number) + grouped[-1].parcel_numbers.sort() + return grouped + def long_label(self): items = [unicode(self.operation or self.associated_file)] items += [unicode(item) for item in [self.section, self.parcel_number] diff --git a/archaeological_operations/templates/ishtar/sheet_operation.html b/archaeological_operations/templates/ishtar/sheet_operation.html new file mode 100644 index 000000000..491304125 --- /dev/null +++ b/archaeological_operations/templates/ishtar/sheet_operation.html @@ -0,0 +1,183 @@ +{% extends "ishtar/sheet.html" %} +{% load i18n %} +{% block content %} +<div class='tool'>{%trans "Export as:"%} <a href='{% url show-operation item.pk "odt" %}'>{%trans "OpenOffice.org file"%}</a>, <a href='{% url show-operation item.pk "pdf" %}'>{%trans "PDF file"%}</a></div> +<h3>{% trans "General"%}</h3> +<p><label>{%trans "Year:"%}</label> <span class='value'>{{ item.year }}</span></p> +{% if item.operation.operation_code %}<p><label>{%trans "Numerical reference:"%}</label> <span class='value'>{{ item.operation_code }}</span></p>{% endif %} + +{% if item.code_patriarche %}<p><label>{%trans "Patriarche OA code:"%}</label> <span class='value'>{{ item.code_patriarche }}</span></p>{%else%} +<p class='alert'>{%trans "Patriarche OA code not yet recorded!"%}</p>{%endif%} + +{#<p><label>{%trans "Operation's name:"%}</label> <span class='value'>{{ item.internal_reference }}</span></p>#} + +<p><label>{%trans "Edition date:"%}</label> <span class='value'>{{ item.history.all.0.history_date }}</span></p> <!-- date = now --> + +{% if item.start_date %}<p><label>{%trans "Begining date:"%}</label> <span class='value'>{{ item.start_date }}</span></p> +<p><label>{%trans "Excavation end date:"%}</label> <span class='value'>{{ item.excavation_end_date|default:"-" }}</span></p> +{%endif%} +{% if item.in_charge %}<p><label>{%trans "Head scientist:"%}</label> <span class='value'>{{ item.in_charge.full_label }}</span></p>{%endif%} +<p><label>{%trans "State:"%}</label> <span class='value'>{% if item.is_active %}{%trans "Active file"%}</span></p> +{% else %}{%trans "Closed operation"%}</span></p> +<p><label>{%trans "Closing date:"%}</label> <span class='value'>{{ item.closing.date }} <strong>{%trans "by" %}</strong> {{ item.closing.user }}</span></p> +{% endif %} +<p><label>{%trans "Type:"%}</label> <span class='value'>{{ item.operation_type }}</span></p> +{% if item.surface %}<p><label>{%trans "Surface:"%}</label> <span class='value'>{{ item.surface }} m<sup>2</sup> ({{ item.surface_ha }} ha)</span></p>{% endif %} +{% if item.cost %}<p><label>{%trans "Cost:"%}</label> <span class='value'>{{ item.cost }} €{% if item.cost_by_m2 %}, ({{ item.cost_by_m2 }} €/m<sup>2</sup>){%endif%}</span></p>{%endif%} +{% if item.duration %}<p><label>{%trans "Duration:"%}</label> <span class='value'>{{ item.duration }} {%trans "Day"%}s</span></p>{%endif%} + +<p><label>{%trans "Remains:"%}</label> <span class='value'>{{ item.remains.all|join:", " }}</span></p> +<p><label>{%trans "Periods:"%}</label> <span class='value'>{{ item.periods.all|join:", " }}</span></p> + +{% if item.associated_file %} +<p><label>{%trans "Associated file:"%}</label> <span class='value'><a href='#' onclick='load_window("{% url show-file item.associated_file.pk ''%}")'>{{ item.associated_file }}</a></span></p><!-- Displayed as Year/index/Commune/Common_name This should be a link to the file sheet of the related file --> +{% if item.associated_file.is_preventive %} +{#{% if item.operator_reference_code %}<p><label>{%trans "Operator's reference code:"%}</label> <span class='value'>{{ item.operator_reference_code }}</span></p>{% endif %}#} +{% if item.associated_file.town_planning_service %}<p><label>{%trans "Town planning service:"%}</label> <span class='value'>{{ item.associated_file.town_planning_service }}</span></p>{% endif %} +{% if item.associated_file.permit_type %}<p><label>{%trans "Permit type:"%}</label> <span class='value'>{{ item.associated_file.permit_type }}</span></p>{% endif %} +{% if item.associated_file.permit_reference %}<p><label>{%trans "Permit reference:"%}</label> <span class='value'>{{ item.associated_file.permit_reference }}</span></p>{% endif %} +{% if item.associated_file.general_contractor.attached_to %}<p><label>{%trans "General contractor organisation:"%}</label> <span class='value'>{{ item.associated_file.general_contractor.attached_to }}</span></p>{% endif %} <!-- Contractor's organisation displayed as concat of Name/Adress/postal_code/city --> +{% if item.associated_file.general_contractor %}<p><label>{%trans "General contractor:"%}</label> <span class='value'>{{ item.associated_file.general_contractor.full_label }}</span></p>{% endif %} +{% endif %} +{% endif %} + +{% if item.comment %}<p><label>{%trans "Comment:"%}</label> <span class='value'>{{ item.comment }}</span></p>{%endif%} + +<h3>{% trans "Localisation"%}</h3> +<p><label>{%trans "Towns:"%}</label> <span class='value'>{{ item.towns.all|join:", " }}</span></p> + +<p><label>{%trans "Main address:"%}</label> <span class='value'>{{ item.associated_file.address }}</span></p> +{% if item.associated_file.address_complement %}<p><label>{%trans "Complement:"%}</label> <span class='value'>{{ item.associated_file.address_complement }}</span></p>{%endif%} +{% if item.associated_file.postal_code %}<p><label>{%trans "Postal code:"%}</label> <span class='value'>{{ item.associated_file.postal_code }}</span></p>{%endif%} + +{% comment %} +<p><label>{%trans "Lambert X:"%}</label> <span class='value'>{{ item.lambert_x }}</span></p> +<p><label>{%trans "Lambert Y:"%}</label> <span class='value'>{{ item.lambert_y }}</span></p> +<p><label>{%trans "Altitude (m NGF):"%}</label> <span class='value'>{{ item.altitude }}</span></p> +{% endcomment %} +<table> + <caption>{%trans "Associated parcels"%}</caption> + <tr> + <th>{% trans "Commune" %}</th> + <th>{% trans "Year" %}</th> + <th>{% trans "Section" %}</th> + <th>{% trans "Parcels" %}</th> + {#<th>{% trans "Owner" %}</th>#} + </tr> + {% for parcel in item.grouped_parcels %} + <tr> + <td class='string'>{{parcel.town}}</td> + <td>{{parcel.year}}</td> + <td>{{parcel.section}}</td> + <td>{{parcel.parcel_numbers|join:", "}}</td> + {#<td class='string'>{{operation.parcel.owner}}</td>#} + </tr> + {% empty %} + <tr><td colspan="4" class='no_items'>{% trans "No parcel associated to this operation" %}</td></tr> + {% endfor %} +</table> + +<table> + <caption>{%trans "Administrative acts"%}</caption> + <tr> + <th>{% trans "Year" %}</th> + <th>{% trans "Reference" %}</th> + <th>{% trans "Type" %}</th> + <th>{% trans "Date" %}</th> + </tr> + {% for act in item.administrative_act.all %} + <tr> + <td>{{act.signature_date.year}}</td> + <td>{{act.ref_sra}}</td> + <td class='string'>{{act.act_type}}</td> + <td class="string">{{act.signature_date}}</td> + </tr> + {% empty %} + <tr><td colspan="4" class='no_items'>{% trans "No acts associated to this operation" %}</td></tr> + {% endfor %} +</table> + +<h3>{% trans "Scientific documentation"%}</h3> +<table> + <caption>{%trans "Documents"%}</caption> + <tr> + <th>{% trans "Title" %}</th> + <th>{% trans "Type" %}</th> + <th>{% trans "Authors" %}</th> + {#<th>{% trans "Localisation" %}</th>#} + </tr> + {% for doc in item.source.all %} + <tr> + <td class='string'>{{ doc.title }}</td> + <td class='string'>{{doc.source_type}}</td> + <td class='string'>{{ doc.authors.all|join:", " }}</td> + {#<td>{{ doc.localisation }}</td>#} + </tr> + {% empty %} + <tr><td colspan="4" class='no_items'>{% trans "No scientific document associated to this operation" %}</td></tr> + {% endfor %} +</table> + +<table> + <caption>{%trans "Context records"%}</caption> + <tr> + <th>{% trans "ID" %}</th> + <th>{% trans "Type" %}</th> + <th>{% trans "Chronology" %}</th> + <th>{% trans "Description" %}</th> + <th>{% trans "Parcel" %}</th> + <th class='link'> </th> + </tr> + {% for context_record in item.context_record.all %} + <tr> + <td class='string'>{{ context_record.label }}</td> + <td class='string'>{{context_record.unit|default:""}}</td> + <td class='string'>{{ context_record.datings.all|join:", " }}</td>{# periods ?#} + <td class='string'>{{ context_record.description }}</td> + <td class='string'>{{ context_record.parcel.section }} - {{context_record.parcel.parcel_number}}</td> + <td class='link'><a href="#" onclick='load_window("{%url show-contextrecord context_record.pk ''%}")'>{% trans "Details" %}</a></td> + </tr> + {% empty %} + <tr><td colspan="6" class='no_items'>{% trans "No context record associated to this operation" %}</td></tr> + {% endfor %} +</table> +<div class='table'> +<table> + <caption>{%trans "Finds"%}</caption> + <tr> + <th>{% trans "Find" %}</th> + <th>{% trans "Material type" %}</th> + <th>{% trans "Context record" %}</th> + <th>{% trans "Periods" %}</th> + <th>{% trans "Description" %}</th> + <th>{% trans "Weight" %}</th> + <th>{% trans "Numbers" %}</th> + <th>{% trans "Parcel" %}</th> + <th class='link'> </th> + </tr> + {% for context_record in item.context_record.all %} + {% for find in context_record.base_finds.all %} + <tr> + <td class="ref">{{ find.full_label }}</td> +{# Displayed as (Patriarche operation code)-(Record unit label)-(Finds label). #} +{# or displayed as (Year)-(index)-(Record unit label)-(Finds label). #} + <td class="ref">{{ find.material_type_label }}</td> + <td>{{find.context_record.label}}</td> + <td class='string'>{{ find.get_last_find.dating}}</td>{# TODO .all|join:", " ? #} + <td class='string'>{{ find.get_last_find.description }}</td> + <td>{{ find.get_last_find.weight }}</td> + <td>{{ find.get_last_find.item_number }}</td> + <td class="ref">{{ context_record.parcel.short_label }}</td> + <td class='link'><a href="#">{% trans "Details" %}</a></td> + {#<a href="#" onclick='load_window("{% url show-find find.pk%}");'>{%trans "Details"%}</a></td>#} + </tr> + {% empty %} + <tr><td colspan="9" class='no_items'>{% trans "No find associated to context record" %} {{context_record.short_label}}</td></tr> + {% endfor %} + {% empty %} + <tr><td colspan="9" class='no_items'>{% trans "No find associated to parcel" %} {{parcel.short_label}} {% trans "(no context record)" %}</td></tr> + {% endfor %} +</table> +</div> + +{% endblock %} diff --git a/archaeological_operations/templates/ishtar/sheet_operation_pdf.html b/archaeological_operations/templates/ishtar/sheet_operation_pdf.html new file mode 100644 index 000000000..9ef0edbf7 --- /dev/null +++ b/archaeological_operations/templates/ishtar/sheet_operation_pdf.html @@ -0,0 +1,18 @@ +{% extends "ishtar/sheet_operation.html" %} +{% block css_head %} +<link rel="stylesheet" href="{{MEDIA_URL}}/media/style_basic.css" /> +{% endblock %} +{% block main_head %} +{{ block.super }} +<div id="pdfheader"> +Ishtar – {{APP_NAME}} – {{item}} +</div> +{% endblock %} +{%block head_sheet%}{%endblock%} +{%block main_foot%} +<div id="pdffooter"> +– <pdf:pagenumber/> – +</div> +</body> +</html> +{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_operation_window.html b/archaeological_operations/templates/ishtar/sheet_operation_window.html new file mode 100644 index 000000000..3accaff42 --- /dev/null +++ b/archaeological_operations/templates/ishtar/sheet_operation_window.html @@ -0,0 +1,3 @@ +{% extends "ishtar/sheet_operation.html" %} +{% block main_head %}{%endblock%} +{% block main_foot %}{%endblock%} diff --git a/archaeological_operations/urls.py b/archaeological_operations/urls.py index 23632f1cf..0da649d2d 100644 --- a/archaeological_operations/urls.py +++ b/archaeological_operations/urls.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2013 É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 @@ -72,5 +72,7 @@ urlpatterns += patterns('archaeological_operations.views', url(r'get-operationsource/(?P<type>.+)?$', 'get_operationsource', name='get-operationsource'), url(r'dashboard_operation/$', 'dashboard_operation', - name='dashboard-operation') + name='dashboard-operation'), + url(r'autocomplete-patriarche/$', 'autocomplete_patriarche', + name='autocomplete-patriarche'), ) diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 9aa2222ba..1ce4c4622 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2013 É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 @@ -30,6 +30,30 @@ from wizards import * from forms import * import models +def autocomplete_patriarche(request, non_closed=True): + person_types = request.user.ishtaruser.person.person_type + if (not request.user.has_perm('ishtar_common.view_operation', + models.Operation) + and not request.user.has_perm('ishtar_common.view_own_operation', + models.Operation) + and not person_types.rights.filter( + wizard__url_name='operation_search').count()): + return HttpResponse(mimetype='text/plain') + if not request.GET.get('term'): + return HttpResponse(mimetype='text/plain') + q = request.GET.get('term') + query = Q() + for q in q.split(' '): + query = query & Q(code_patriarche__startswith=q) + if non_closed: + query = query & Q(end_date__isnull=True) + limit = 15 + operations = models.Operation.objects.filter(query)[:limit] + data = json.dumps([{'id':operation.code_patriarche, + 'value':operation.code_patriarche} + for operation in operations]) + return HttpResponse(data, mimetype='text/plain') + def autocomplete_operation(request, non_closed=True): person_types = request.user.ishtaruser.person.person_type if (not request.user.has_perm('ishtar_common.view_operation', @@ -70,9 +94,19 @@ def get_available_operation_code(request, year=None): get_operation = get_item(models.Operation, 'get_operation', 'operation', bool_fields = ['end_date__isnull'], + dated_fields = ['start_date__lte', 'start_date__gte', + 'excavation_end_date__lte', 'excavation_end_date__gte'], extra_request_keys={'common_name':'common_name__icontains', 'end_date':'end_date__isnull', - 'year_index':('year', 'operation_code')}) + 'year_index':('year', 'operation_code'), + 'start_before':'start_date__lte', + 'start_after':'start_date__gte', + 'end_before':'excavation_end_date__lte', + 'end_after':'excavation_end_date__gte', + 'parcel_0':'parcels__section', + 'parcel_1':'parcels__parcel_number', + }, + ) show_operation = show_item(models.Operation, 'operation') revert_operation = revert_item(models.Operation) @@ -88,7 +122,6 @@ get_administrativeactop = get_item(models.AdministrativeAct, 'operation__towns':'operation__towns__pk', 'act_type__intented_to':'act_type__intented_to'}) - def dashboard_operation(request, *args, **kwargs): """ Operation dashboard diff --git a/archaeological_operations/widgets.py b/archaeological_operations/widgets.py new file mode 100644 index 000000000..0e84b2047 --- /dev/null +++ b/archaeological_operations/widgets.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2013 É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 +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +from django import forms +from django.forms import widgets + +class ParcelWidget(widgets.MultiWidget): + def __init__(self, attrs=None): + if not attrs: + attrs = {'class':'widget-parcel'} + elif 'class' not in attrs: + attrs['class'] = 'widget-parcel' + else: + attrs['class'] += ' widget-parcel' + _widgets = ( + widgets.TextInput(attrs=attrs), + widgets.TextInput(attrs=attrs), + ) + super(ParcelWidget, self).__init__(_widgets, attrs) + + def decompress(self, value): + if value: + return value + return [None, None] + + def format_output(self, rendered_widgets): + return u' / '.join(rendered_widgets) diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index 3281a5723..4205144e6 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -27,16 +27,22 @@ from django.utils.translation import ugettext_lazy as _ from ishtar_common.wizards import Wizard, ClosingWizard, DeletionWizard, \ SourceWizard import models +from forms import ParcelForm class OperationWizard(Wizard): model = models.Operation object_parcel_type = 'operation' + parcel_step_key = 'parcelsgeneral-' def get_template_names(self): templates = super(OperationWizard, self).get_template_names() - current_step = self.steps. current + current_step = self.steps.current if current_step.startswith('towns-'): - templates = ['ishtar/wizard/towns_wizard.html'] + templates + #templates = ['ishtar/wizard/towns_wizard.html'] + templates + pass + if current_step.startswith('parcels-') or \ + current_step.startswith('parcelsgeneral-') : + templates = ['ishtar/wizard/parcels_wizard.html'] + templates return templates def get_context_data(self, form, **kwargs): @@ -121,7 +127,7 @@ class OperationWizard(Wizard): Show a specific warning if no archaelogical file is provided """ datas = super(OperationWizard, self).get_formated_datas(forms) - # if the general town form is used the advertissement is pertinent + # if the general town form is used the advertissement is relevant has_no_af = [form.prefix for form in forms if form.prefix == 'townsgeneral-operation'] and True if has_no_af: @@ -130,6 +136,33 @@ class OperationWizard(Wizard): + datas return datas + def get_form_initial(self, step, data=None): + initial = super(OperationWizard, self).get_form_initial(step) + self.form_initialized = False + if not step.startswith(self.parcel_step_key): + return initial + if initial: + default = initial[-1].copy() + if 'parcel_number' in default: + default.pop('parcel_number') + initial.append(default) + # necessary to get the appropriate form number + self.form_initialized = True + elif data: + numbers, keys = set(), set() + for k in data: + items = k.split('-') + try: + numbers.add(int(items[-2])) + except (ValueError, IndexError): + continue + keys.add(items[-1]) + if max(numbers) - 1: + initial = [dict([(k, data[step+'-'+unicode(max(numbers)-1)+'-'+k]) + for k in keys if k != 'parcel_number'])] + self.form_initialized = True + return initial + class OperationModificationWizard(OperationWizard): modification = True @@ -145,7 +178,7 @@ class OperationDeletionWizard(DeletionWizard): class OperationSourceWizard(SourceWizard): model = models.OperationSource - def get_form_initial(self, step): + def get_form_initial(self, step, data=None): initial = super(OperationSourceWizard, self).get_form_initial(step) # put default index and operation_id field in the main source form general_form_key = 'selec-' + self.url_name |
