From f6f70c2d270644a520c6f2f1bcf718839c5f489c Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 3 Apr 2013 18:02:02 +0200 Subject: OPE: search OPE by PATRIARCHE code (refs #430) --- archaeological_operations/forms.py | 5 +++++ archaeological_operations/models.py | 1 + archaeological_operations/urls.py | 6 ++++-- archaeological_operations/views.py | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index f5f0fea99..62425b68d 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -95,6 +95,11 @@ ParcelFormSet.form_label = _(u"Parcels") class OperationSelect(forms.Form): 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=[]) diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 399b536e2..675666dbb 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -163,6 +163,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 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 +# Copyright (C) 2010-2013 É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 @@ -72,5 +72,7 @@ urlpatterns += patterns('archaeological_operations.views', url(r'get-operationsource/(?P.+)?$', '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..96fd2efd2 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -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', -- cgit v1.2.3 From c693630090f670ca33981dcdf0b135fdd7432972 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 12:48:06 +0200 Subject: Operations: search operations by dates (refs #1187) --- archaeological_operations/forms.py | 8 ++++++++ archaeological_operations/views.py | 8 +++++++- ishtar_common/views.py | 15 +++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 62425b68d..f2a81a85d 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -106,6 +106,14 @@ class OperationSelect(forms.Form): remains = forms.ChoiceField(label=_(u"Remains"), choices=models.RemainType.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) end_date = forms.NullBooleanField(label=_(u"Is open?")) def __init__(self, *args, **kwargs): diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 96fd2efd2..e12b8edd6 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -94,9 +94,15 @@ 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',}) show_operation = show_item(models.Operation, 'operation') revert_operation = revert_item(models.Operation) diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 4a1a656d9..83833e517 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -173,7 +173,7 @@ HIERARCHIC_LEVELS = 5 HIERARCHIC_FIELDS = ['period', 'unit', 'material_type'] PRIVATE_FIELDS = ('id', 'history_modifier', 'order') def get_item(model, func_name, default_name, extra_request_keys=[], - base_request={}, bool_fields=[]): + base_request={}, bool_fields=[], dated_fields=[]): """ Generic treatment of tables """ @@ -213,7 +213,18 @@ def get_item(model, func_name, default_name, extra_request_keys=[], dct.pop(k) else: dct[k] = dct[k] == u"2" and True or False - + for k in dated_fields: + if k in dct: + if not dct[k]: + dct.pop(k) + try: + items = dct[k].split('/') + assert len(items) == 3 + dct[k] = datetime.date(*map(lambda x: int(x), + reversed(items)) + ).strftime('%Y-%m-%d') + except AssertionError: + dct.pop(k) # manage hierarchic conditions or_reqs = [] for req in dct.copy(): -- cgit v1.2.3 From f7bf3b773787d336319518786f396cbf0342e567 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 12:59:26 +0200 Subject: Operation: add search by person in charge (refs #1185) --- archaeological_operations/forms.py | 8 +++++++- archaeological_operations/views.py | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index f2a81a85d..5501857ba 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 +# Copyright (C) 2010-2013 É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 @@ -103,6 +103,12 @@ class OperationSelect(forms.Form): 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()) year = forms.IntegerField(label=_("Year")) diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index e12b8edd6..4650e4764 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -118,7 +118,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 -- cgit v1.2.3 From 157259f4a9a030367f123ae1b2802c529b151197 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 14:58:05 +0200 Subject: Forms (operations, context records, files): add search by parcel (refs #575) --- archaeological_context_records/forms.py | 16 +++++++++--- archaeological_context_records/views.py | 7 ++++-- archaeological_files/forms.py | 17 ++++++++++--- archaeological_files/views.py | 8 ++++-- archaeological_finds/forms.py | 4 +-- archaeological_operations/forms.py | 24 +++++++++++++++--- archaeological_operations/views.py | 14 ++++++++++- archaeological_operations/widgets.py | 43 +++++++++++++++++++++++++++++++++ archaeological_warehouse/forms.py | 5 ++-- ishtar_common/forms.py | 6 ++++- ishtar_common/forms_common.py | 4 +-- ishtar_common/static/media/style.css | 3 +++ ishtar_common/views.py | 2 +- ishtar_common/widgets.py | 6 ++--- 14 files changed, 132 insertions(+), 27 deletions(-) create mode 100644 archaeological_operations/widgets.py diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py index 41e4a1e20..fce5193d6 100644 --- a/archaeological_context_records/forms.py +++ b/archaeological_context_records/forms.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -36,16 +36,17 @@ import models from ishtar_common import widgets from ishtar_common.forms import FinalForm, FinalForm, FormSet, \ - formset_factory, get_now, reverse_lazy, get_form_selection + formset_factory, get_now, reverse_lazy, get_form_selection, TableSelect from ishtar_common.forms_common import get_town_field, SourceForm, \ SourceSelect, AuthorFormset -from archaeological_operations.forms import OperationSelect +from archaeological_operations.forms import OperationSelect, ParcelField -class RecordSelect(forms.Form): +class RecordSelect(TableSelect): parcel__town = get_town_field() operation__year = forms.IntegerField(label=_(u"Year")) datings__period = forms.ChoiceField(label=_(u"Period"), choices=[]) unit = forms.ChoiceField(label=_(u"Unit type"), choices=[]) + parcel = ParcelField(label=_("Parcel (section/number)")) def __init__(self, *args, **kwargs): super(RecordSelect, self).__init__(*args, **kwargs) self.fields['datings__period'].choices = Period.get_types() @@ -53,6 +54,13 @@ class RecordSelect(forms.Form): self.fields['unit'].choices = models.Unit.get_types() self.fields['unit'].help_text = models.Unit.get_help() + def get_input_ids(self): + ids = super(RecordSelect, self).get_input_ids() + ids.pop(ids.index('parcel')) + ids.append('parcel_0') + ids.append('parcel_1') + return ids + class RecordFormSelection(forms.Form): form_label = _("Context record search") associated_models = {'pk':models.ContextRecord} diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index bd18ffa49..c59446bcf 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -30,7 +30,10 @@ get_contextrecord = get_item(models.ContextRecord, 'get_contextrecord', 'contextrecord', extra_request_keys={'parcel__town':'parcel__town__pk', 'operation__year':'operation__year__contains', - 'datings__period':'datings__period__pk'},) + 'datings__period':'datings__period__pk', + 'parcel_0':'operation__parcels__section', + 'parcel_1':'operation__parcels__parcel_number', + },) get_contextrecordsource = get_item(models.ContextRecordSource, 'get_contextrecordsource', 'contextrecordsource', extra_request_keys={ diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 564d0c6fc..ea12c984c 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -36,13 +36,14 @@ from ishtar_common.models import Person, PersonType, Town, Organization, \ from archaeological_operations.models import ActType, AdministrativeAct import models from ishtar_common.forms import FinalForm, FormSet, ClosingDateFormSelection, \ - formset_factory, get_now, reverse_lazy + formset_factory, get_now, reverse_lazy, TableSelect from ishtar_common.forms_common import get_town_field, get_person_field from archaeological_operations.forms import AdministrativeActOpeForm, \ - AdministrativeActOpeFormSelection, FinalAdministrativeActDeleteForm + AdministrativeActOpeFormSelection, FinalAdministrativeActDeleteForm, \ + ParcelField from ishtar_common import widgets -class FileSelect(forms.Form): +class FileSelect(TableSelect): towns = get_town_field() in_charge = get_person_field(label=_(u"Person in charge"), person_type='sra_agent') @@ -50,12 +51,20 @@ class FileSelect(forms.Form): choices=models.FileType.get_types()) saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[]) year = forms.IntegerField(label=_("Year")) + parcel = ParcelField(label=_("Parcel (section/number)")) 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() + def get_input_ids(self): + ids = super(FileSelect, self).get_input_ids() + ids.pop(ids.index('parcel')) + ids.append('parcel_0') + ids.append('parcel_1') + return ids + class FileFormSelection(forms.Form): form_label = _("Archaeological file search") associated_models = {'pk':models.File} @@ -170,7 +179,7 @@ class FinalFileDeleteForm(FinalForm): confirm_msg = " " confirm_end_msg = _(u"Would you like to delete this archaelogical file ?") -class AdministrativeActFileSelect(forms.Form): +class AdministrativeActFileSelect(TableSelect): associated_file__towns = get_town_field() act_type = forms.ChoiceField(label=_("Act type"), choices=[]) diff --git a/archaeological_files/views.py b/archaeological_files/views.py index 3ef8c0f28..2b5003911 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -60,7 +60,11 @@ def autocomplete_file(request): for file in files]) return HttpResponse(data, mimetype='text/plain') -get_file = get_item(models.File, 'get_file', 'file') +get_file = get_item(models.File, 'get_file', 'file', + extra_request_keys={'parcel_0':'operations__parcels__section', + 'parcel_1':'operations__parcels__parcel_number', + }, + ) show_file = show_item(models.File, 'file') revert_file = revert_item(models.File) diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index c5480d8a8..feaad0e23 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -39,7 +39,7 @@ import models from ishtar_common import widgets from ishtar_common.forms import FinalForm, FormSet, FloatField, \ - formset_factory, get_now, get_form_selection, reverse_lazy + formset_factory, get_now, get_form_selection, reverse_lazy, TableSelect from ishtar_common.forms_common import get_town_field, \ SourceForm, SourceSelect, SourceDeletionForm, AuthorFormset from archaeological_context_records.forms import RecordFormSelection @@ -81,7 +81,7 @@ class DateForm(forms.Form): self.fields['dating__dating_type'].choices = DatingType.get_types() self.fields['dating__dating_type'].help_text = DatingType.get_help() -class FindSelect(forms.Form): +class FindSelect(TableSelect): base_finds__context_record__parcel__town = get_town_field() base_finds__context_record__operation__year = forms.IntegerField( label=_(u"Year")) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 5501857ba..547daf828 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -35,13 +35,23 @@ 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 + 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' @@ -93,7 +103,7 @@ 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( @@ -120,6 +130,7 @@ class OperationSelect(forms.Form): 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): @@ -127,6 +138,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} @@ -425,7 +443,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/views.py b/archaeological_operations/views.py index 4650e4764..84f208bf3 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -92,6 +92,14 @@ def get_available_operation_code(request, year=None): data = json.dumps({'id':models.Operation.get_available_operation_code(year)}) return HttpResponse(data, mimetype='text/plain') +def get_parcel_parser(key_section, key_number): + def func(dct): + print dct + section, number = dct.get(key_section), dct.get(key_number) + if not section or not number: + return {} + return {key_section:section, key_number:number} + get_operation = get_item(models.Operation, 'get_operation', 'operation', bool_fields = ['end_date__isnull'], dated_fields = ['start_date__lte', 'start_date__gte', @@ -102,7 +110,11 @@ get_operation = get_item(models.Operation, 'get_operation', 'operation', 'start_before':'start_date__lte', 'start_after':'start_date__gte', 'end_before':'excavation_end_date__lte', - 'end_after':'excavation_end_date__gte',}) + '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) 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 + +# 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. + +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_warehouse/forms.py b/archaeological_warehouse/forms.py index 2e1bfcc05..69bb2cae3 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -27,7 +27,8 @@ from ishtar_common.models import Person, valid_id from archaeological_finds.models import TreatmentType import models from ishtar_common import widgets -from ishtar_common.forms import name_validator, reverse_lazy, get_form_selection +from ishtar_common.forms import name_validator, reverse_lazy, \ + get_form_selection, TableSelect from archaeological_finds.forms import FindMultipleFormSelection def get_warehouse_field(label=_(u"Warehouse"), required=True): @@ -109,7 +110,7 @@ class ContainerForm(forms.Form): new_item.save() return new_item -class ContainerSelect(forms.Form): +class ContainerSelect(TableSelect): location = get_warehouse_field() container_type = forms.ChoiceField(label=_(u"Container type"), choices=[]) reference = forms.CharField(label=_(u"Reference")) diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index d66d6d4cc..cb007442e 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2011 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -101,6 +101,10 @@ class FormSet(BaseFormSet): form.fields[DELETION_FIELD_NAME].label = '' form.fields[DELETION_FIELD_NAME].widget = widgets.DeleteWidget() +class TableSelect(forms.Form): + def get_input_ids(self): + return self.fields.keys() + def get_now(): format = formats.get_format('DATE_INPUT_FORMATS')[0] value = datetime.datetime.now().strftime(format) diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 34a930e36..52fcfc97a 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -37,7 +37,7 @@ from django.utils.translation import ugettext_lazy as _ import models import widgets -from forms import FinalForm, FormSet, reverse_lazy, name_validator +from forms import FinalForm, FormSet, reverse_lazy, name_validator, TableSelect def get_town_field(label=_(u"Town"), required=True): help_text = _(u"

Type name, department code and/or postal code of the " @@ -234,7 +234,7 @@ class SourceForm(forms.Form): super(SourceForm, self).__init__(*args, **kwargs) self.fields['source_type'].choices = models.SourceType.get_types() -class SourceSelect(forms.Form): +class SourceSelect(TableSelect): authors = forms.IntegerField( widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \ 'autocomplete-author', associated_model=models.Author), diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css index 2aa673b51..cad9a224a 100644 --- a/ishtar_common/static/media/style.css +++ b/ishtar_common/static/media/style.css @@ -528,3 +528,6 @@ a.remove{ border:1px solid; } +.widget-parcel{ + width:60px; +} diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 83833e517..54523996f 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -173,7 +173,7 @@ HIERARCHIC_LEVELS = 5 HIERARCHIC_FIELDS = ['period', 'unit', 'material_type'] PRIVATE_FIELDS = ('id', 'history_modifier', 'order') def get_item(model, func_name, default_name, extra_request_keys=[], - base_request={}, bool_fields=[], dated_fields=[]): + base_request={}, bool_fields=[], dated_fields=[]): """ Generic treatment of tables """ diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index ecc48a1e8..1fd0b6ac0 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -219,8 +219,8 @@ class JQueryJqGrid(forms.RadioSelect): rendered += "\n

%s

\n" % unicode(_("Search and select an item")) extra_cols = [] col_names, col_idx = [], [] - for k in self.form.fields: - field = self.form.fields[k] + for k in self.form.get_input_ids(): + #field = self.form.fields[k] col_idx.append(u'"%s"' % k) for field_name in getattr(self.associated_model, self.table_cols): field = self.associated_model @@ -292,7 +292,7 @@ class JQueryJqGrid(forms.RadioSelect): } } var mygrid = jQuery("#grid_%(name)s"); - var url = "%(source)s?submited=1&" + data; + var url = "%(source)s?submited=1&" + data; mygrid.setGridParam({url:url}); mygrid.trigger("reloadGrid"); return false; -- cgit v1.2.3 From 6c225450c36c0fb58df61dd641f25fa78db2c7a5 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 18:12:56 +0200 Subject: Rename and move sheets templates --- .../templates/ishtar/sheet_contextrecord.html | 135 +++++++++++++++ .../ishtar/sheet_contextrecord_window.html | 3 + .../templates/ishtar/sheet_file.html | 132 +++++++++++++++ .../templates/ishtar/sheet_file_pdf.html | 18 ++ .../templates/ishtar/sheet_file_window.html | 3 + .../templates/ishtar/sheet_operation.html | 183 +++++++++++++++++++++ .../templates/ishtar/sheet_operation_pdf.html | 18 ++ .../templates/ishtar/sheet_operation_window.html | 3 + ishtar_common/templates/ishtar/sheet.html | 30 ++++ ishtar_common/templates/sheet.html | 30 ---- ishtar_common/templates/sheet_contextrecord.html | 135 --------------- .../templates/sheet_contextrecord_window.html | 3 - ishtar_common/templates/sheet_file.html | 132 --------------- ishtar_common/templates/sheet_file_pdf.html | 18 -- ishtar_common/templates/sheet_file_window.html | 3 - ishtar_common/templates/sheet_operation.html | 183 --------------------- ishtar_common/templates/sheet_operation_pdf.html | 18 -- .../templates/sheet_operation_window.html | 3 - ishtar_common/views.py | 8 +- 19 files changed, 529 insertions(+), 529 deletions(-) create mode 100644 archaeological_context_records/templates/ishtar/sheet_contextrecord.html create mode 100644 archaeological_context_records/templates/ishtar/sheet_contextrecord_window.html create mode 100644 archaeological_files/templates/ishtar/sheet_file.html create mode 100644 archaeological_files/templates/ishtar/sheet_file_pdf.html create mode 100644 archaeological_files/templates/ishtar/sheet_file_window.html create mode 100644 archaeological_operations/templates/ishtar/sheet_operation.html create mode 100644 archaeological_operations/templates/ishtar/sheet_operation_pdf.html create mode 100644 archaeological_operations/templates/ishtar/sheet_operation_window.html create mode 100644 ishtar_common/templates/ishtar/sheet.html delete mode 100644 ishtar_common/templates/sheet.html delete mode 100644 ishtar_common/templates/sheet_contextrecord.html delete mode 100644 ishtar_common/templates/sheet_contextrecord_window.html delete mode 100644 ishtar_common/templates/sheet_file.html delete mode 100644 ishtar_common/templates/sheet_file_pdf.html delete mode 100644 ishtar_common/templates/sheet_file_window.html delete mode 100644 ishtar_common/templates/sheet_operation.html delete mode 100644 ishtar_common/templates/sheet_operation_pdf.html delete mode 100644 ishtar_common/templates/sheet_operation_window.html diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html new file mode 100644 index 000000000..d8e06f022 --- /dev/null +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html @@ -0,0 +1,135 @@ +{% extends "ishtar/sheet.html" %} +{% load i18n %} +{% block content %} + + +

{% trans "Context Record"%}

+ +{% if item.operation.code_patriarche %} +

+{% else %} +

+

+{%endif%} +{{item.full_label}}

+{%if item.unit %} +

{{ item.unit }}

+{%endif%} +

{{ item.datings.all|join:", " }}

+

{{ item.parcel.town }}

+

{{ item.parcel.short_label }}

+ +{% if item.description or item.lenght or item.width or item.depth %} +

{% trans "Description"%}

+ +

{{ item.description }}

+{% if item.lenght %}

{{ item.length }}

{%endif%} +{% if item.width %}

{{ item.width }}

{%endif%} +{% if item.depth %}

{{ item.depth }}

{%endif%} +{% endif %} + +{% if item.activity or item.identification or item.interpretation %} +

{% trans "Interpretation"%}

+ +{% if item.activity %}

{{ item.activity }}

{%endif%} +{% if item.identification %}

{{ item.identification }}

{%endif%} +{% if item.interpretation %}

{{ item.interpretation }}

{%endif%} +{% endif %} + +{% if item.taq or item.taq_estimated or item.tpq or item.tpq_estimated %} +

{% trans "Datations"%}

+{% if item.taq %}

{{ item.taq }}

{%endif%} +{% if item.taq_estimated %}

{{ item.taq_estimated }}

{%endif%} +{% if item.tpq %}

{{ item.tpq }}

{%endif%} +{% if item.tpq_estimated %}

{{ item.tpq_estimated }}

{%endif%} +{%endif%} + +{% if item.operation %} +

{% trans "Operation resume"%}

+

{{ item.operation.year }}

+

{{ item.operation.operation_code }}

+{% if item.operation.code_patriarche %} +

+{{ item.operation.code_patriarche }}

+{% else %}

+{%endif%} +{#

{{ item.operation.internal_reference }}

#} +

+{{ item.operation.in_charge.full_label }}

+

+{% if item.operation.is_active %} +{%trans "Active file"%}

+{% else %} +{%trans "Closed operation"%}

+

{{ item.operation.closing.date }} +{%trans "by" %} {{ item.operation.closing.user }}

+{% endif %} +

{{ item.operation.operation_type }}

+

{{ item.operation.remains.all|join:", " }}

+

{{ item.operation.periods.all|join:", " }}

+{% if item.operation.comment %}

{{ item.operation.comment }}

{%endif%} +

{% trans "Localisation"%}

+

{{ item.operation.towns.all|join:", " }}

+

+{{ item.operation }}

+{# TODO: Displayed as Year/index/Commune/Common_name This should be a link to the file sheet of the related operation #} +{% else %}

+{% endif %} + + + + + + + + {##} + + {% for doc in item.source.all %} + + + + + {##} + + {% empty %} + + {% endfor %} +
{%trans "Documents"%}
{% trans "Title" %}{% trans "Type" %}{% trans "Authors" %}{% trans "Localisation" %}
{{ doc.title }}{{doc.source_type}}{{ doc.authors.all|join:", " }}{{ doc.localisation }}
{% trans "No document associated to this context record" %}
+ + + + + + + + + + + + + + + {% for find in item.base_finds.all %} + + +{# Displayed as (Patriarche operation code)-(Record unit label)-(Finds label). #} +{# or displayed as (Year)-(index)-(Record unit label)-(Finds label). #} + +{# Displayed as (Patriarche operation code)-(Record unit label)-(material code)-(Finds label indexed by material type). #} +{# or displayed as (Year)-(index)-(Record unit label)-(material code)-(Finds label indexed by material type) #} + + + {# TODO .all|join:", " ? #} + + + + + + {#{%trans "Details"%}#} + + {% empty %} + + {% endfor %} +
{%trans "Finds"%}
{% trans "Find" %}{% trans "Material type" %}{% trans "Context record" %}{% trans "Periods" %}{% trans "Description" %}{% trans "Weight" %}{% trans "Numbers" %}{% trans "Parcel" %} 
{{ find.full_label }}{{ find.material_type_label }}{{find.context_record}}{{ find.get_last_find.dating}}{{ find.get_last_find.description }}{{ find.get_last_find.weight }}{{ find.get_last_find.item_number }}{{ item.context_record.parcel.short_label }}
{% trans "No find associated to this context record" %}
+ +{% endblock %} diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord_window.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord_window.html new file mode 100644 index 000000000..b485ebd47 --- /dev/null +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord_window.html @@ -0,0 +1,3 @@ +{% extends "ishtar/sheet_contextrecord.html" %} +{% block main_head %}{%endblock%} +{% block main_foot %}{%endblock%} diff --git a/archaeological_files/templates/ishtar/sheet_file.html b/archaeological_files/templates/ishtar/sheet_file.html new file mode 100644 index 000000000..1b58aa332 --- /dev/null +++ b/archaeological_files/templates/ishtar/sheet_file.html @@ -0,0 +1,132 @@ +{% extends "ishtar/sheet.html" %} +{% load i18n %} +{% block content %} +{% if previous or next %} +
+{%if previous%} +{%trans "Previous version"%} ({{previous}}) +{% endif %} +{% if previous and next %} - {% endif %} +{%if next%} +Rollback - +{%trans "Next version"%} ({{next}}) +{% endif %} +
+{% endif %} + +

{% trans "General"%}

+

{{ item.year }}

+

{{ item.numeric_reference }}

+ +

{{ item.internal_reference }}

+ +

{{ item.history_date }}

+{% if item.reception_date %}

{{ item.reception_date }}

{% endif %} +

{{ item.creation_date }}

+{% comment %} +{% if item.deadline_date and not item.acts %} +

{% item.deadline_date %}

+{% endif %} +{% endcomment %} + +

{{ item.in_charge.full_label }}

+

{% if item.is_active %}{%trans "Active file"%}

+{% else %}{%trans "Closed file"%}

+

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

+{% endif %} + +

{{ item.file_type }}

+ +{% if item.related_file %}

{{ item.related_file }}

{% endif %} +{% if item.comment %}

{{ item.comment }}

{%endif%} + +

{% trans "Localisation"%}

+

{{ item.towns.all|join:", " }}

+ +

{{ item.address }}

+{% if item.address_complement %}

{{ item.address_complement }}

{%endif%} +{% if item.postal_code %}

{{ item.postal_code }}

{%endif%} + +

{% if item.total_surface %} {{ item.total_surface }} m2 ({{ item.total_surface_ha }} ha){%endif%}

+ + + +{% if item.is_preventive %} +

{% trans "Preventive archaelogical file"%}

+

{{ item.total_developed_surface }} m2 ({{ item.total_developed_surface_ha }} ha)

+

{{ item.saisine_type }}

+{% if item.town_planning_service %}

{{ item.town_planning_service }}

{% endif %} +{% if item.permit_type %}

{{ item.permit_type }}

{% endif %} +{% if item.permit_reference %}

{{ item.permit_reference }}

{% endif %} +{% if item.general_contractor.attached_to %}

{{ item.general_contractor.attached_to }}

{% endif %} +{% if item.general_contractor %}

{{ item.general_contractor.full_label }}

{% endif %} +{% endif %} + + + + + + + + + + {% for act in item.administrative_act.all %} + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Admninistrative acts"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No administrative act associated to this archaelogical file" %}
+ + + + + + + + + + + + + + {% for operation in item.operations.all %} + + + + + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Associated operations"%}
{% trans "Year" %}{% trans "Reference" %}Code Patriarche{% trans "Type" %}{% trans "In charge" %}{% trans "Start date" %}{% trans "Excavation end date" %} 
{{operation.year}}{{operation.operation_code}}{{operation.code_patriarche|default:""}}{{operation.operation_type}}{{operation.in_charge|default:""}}{{operation.start_date|default:""}}{{operation.excavation_end_date|default:""}}
{% trans "No operation associated to this archaelogical file" %}
+ + + + + + + + + + {% for act in item.operation_acts %} + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Admninistrative acts linked to associated operations"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No administrative act linked to operations" %}
+{% endblock %} diff --git a/archaeological_files/templates/ishtar/sheet_file_pdf.html b/archaeological_files/templates/ishtar/sheet_file_pdf.html new file mode 100644 index 000000000..29a4f4dec --- /dev/null +++ b/archaeological_files/templates/ishtar/sheet_file_pdf.html @@ -0,0 +1,18 @@ +{% extends "ishtar/sheet_file.html" %} +{% block css_head %} + +{% endblock %} +{% block main_head %} +{{ block.super }} +
+Ishtar – {{APP_NAME}} – {{item}} +
+{% endblock %} +{%block head_sheet%}{%endblock%} +{%block main_foot%} +
+– – +
+ + +{%endblock%} diff --git a/archaeological_files/templates/ishtar/sheet_file_window.html b/archaeological_files/templates/ishtar/sheet_file_window.html new file mode 100644 index 000000000..e3486c052 --- /dev/null +++ b/archaeological_files/templates/ishtar/sheet_file_window.html @@ -0,0 +1,3 @@ +{% extends "ishtar/sheet_file.html" %} +{% block main_head %}{%endblock%} +{% block main_foot %}{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_operation.html b/archaeological_operations/templates/ishtar/sheet_operation.html new file mode 100644 index 000000000..1698f0224 --- /dev/null +++ b/archaeological_operations/templates/ishtar/sheet_operation.html @@ -0,0 +1,183 @@ +{% extends "ishtar/sheet.html" %} +{% load i18n %} +{% block content %} + +

{% trans "General"%}

+

{{ item.year }}

+{% if item.operation.operation_code %}

{{ item.operation_code }}

{% endif %} + +{% if item.code_patriarche %}

{{ item.code_patriarche }}

{%else%} +

{%trans "Patriarche OA code not yet recorded!"%}

{%endif%} + +{#

{{ item.internal_reference }}

#} + +

{{ item.history.all.0.history_date }}

+ +{% if item.start_date %}

{{ item.start_date }}

+

{{ item.excavation_end_date|default:"-" }}

+{%endif%} +{% if item.in_charge %}

{{ item.in_charge.full_label }}

{%endif%} +

{% if item.is_active %}{%trans "Active file"%}

+{% else %}{%trans "Closed operation"%}

+

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

+{% endif %} +

{{ item.operation_type }}

+{% if item.surface %}

{{ item.surface }} m2 ({{ item.surface_ha }} ha)

{% endif %} +{% if item.cost %}

{{ item.cost }} €{% if item.cost_by_m2 %}, ({{ item.cost_by_m2 }} €/m2){%endif%}

{%endif%} +{% if item.duration %}

{{ item.duration }} {%trans "Day"%}s

{%endif%} + +

{{ item.remains.all|join:", " }}

+

{{ item.periods.all|join:", " }}

+ +{% if item.associated_file %} +

{{ item.associated_file }}

+{% if item.associated_file.is_preventive %} +{#{% if item.operator_reference_code %}

{{ item.operator_reference_code }}

{% endif %}#} +{% if item.associated_file.town_planning_service %}

{{ item.associated_file.town_planning_service }}

{% endif %} +{% if item.associated_file.permit_type %}

{{ item.associated_file.permit_type }}

{% endif %} +{% if item.associated_file.permit_reference %}

{{ item.associated_file.permit_reference }}

{% endif %} +{% if item.associated_file.general_contractor.attached_to %}

{{ item.associated_file.general_contractor.attached_to }}

{% endif %} +{% if item.associated_file.general_contractor %}

{{ item.associated_file.general_contractor.full_label }}

{% endif %} +{% endif %} +{% endif %} + +{% if item.comment %}

{{ item.comment }}

{%endif%} + +

{% trans "Localisation"%}

+

{{ item.towns.all|join:", " }}

+ +

{{ item.associated_file.address }}

+{% if item.associated_file.address_complement %}

{{ item.associated_file.address_complement }}

{%endif%} +{% if item.associated_file.postal_code %}

{{ item.associated_file.postal_code }}

{%endif%} + +{% comment %} +

{{ item.lambert_x }}

+

{{ item.lambert_y }}

+

{{ item.altitude }}

+{% endcomment %} + + + + + + + + {##} + + {% for parcel in item.parcels.all %} + + + + + + {##} + + {% empty %} + + {% endfor %} +
{%trans "Associated parcels"%}
{% trans "Commune" %}{% trans "Year" %}{% trans "Section" %}{% trans "Parcel" %}{% trans "Owner" %}
{{parcel.town}}{{parcel.year}}{{parcel.section}}{{parcel.parcel_number}}{{operation.parcel.owner}}
{% trans "No parcel associated to this operation" %}
+ + + + + + + + + + {% for act in item.administrative_act.all %} + + + + + + + {% empty %} + + {% endfor %} +
{%trans "Admninistrative acts"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No acts associated to this operation" %}
+ +

{% trans "Scientific documentation"%}

+ + + + + + + {##} + + {% for doc in item.source.all %} + + + + + {##} + + {% empty %} + + {% endfor %} +
{%trans "Documents"%}
{% trans "Title" %}{% trans "Type" %}{% trans "Authors" %}{% trans "Localisation" %}
{{ doc.title }}{{doc.source_type}}{{ doc.authors.all|join:", " }}{{ doc.localisation }}
{% trans "No scientific document associated to this operation" %}
+ + + + + + + + + + + + {% for context_record in item.context_record.all %} + + + + {# periods ?#} + + + + + {% empty %} + + {% endfor %} +
{%trans "Context records"%}
{% trans "ID" %}{% trans "Type" %}{% trans "Chronology" %}{% trans "Description" %}{% trans "Parcel" %} 
{{ context_record.label }}{{context_record.unit|default:""}}{{ context_record.datings.all|join:", " }}{{ context_record.description }}{{ context_record.parcel.section }} - {{context_record.parcel.parcel_number}}
{% trans "No context record associated to this operation" %}
+
+ + + + + + + + + + + + + + {% for context_record in item.context_record.all %} + {% for find in context_record.base_finds.all %} + + +{# Displayed as (Patriarche operation code)-(Record unit label)-(Finds label). #} +{# or displayed as (Year)-(index)-(Record unit label)-(Finds label). #} + + + {# TODO .all|join:", " ? #} + + + + + + {#{%trans "Details"%}#} + + {% empty %} + + {% endfor %} + {% empty %} + + {% endfor %} +
{%trans "Finds"%}
{% trans "Find" %}{% trans "Material type" %}{% trans "Context record" %}{% trans "Periods" %}{% trans "Description" %}{% trans "Weight" %}{% trans "Numbers" %}{% trans "Parcel" %} 
{{ find.full_label }}{{ find.material_type_label }}{{find.context_record.label}}{{ find.get_last_find.dating}}{{ find.get_last_find.description }}{{ find.get_last_find.weight }}{{ find.get_last_find.item_number }}{{ context_record.parcel.short_label }}
{% trans "No find associated to context record" %} {{context_record.short_label}}
{% trans "No find associated to parcel" %} {{parcel.short_label}} {% trans "(no context record)" %}
+
+ +{% 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 %} + +{% endblock %} +{% block main_head %} +{{ block.super }} +
+Ishtar – {{APP_NAME}} – {{item}} +
+{% endblock %} +{%block head_sheet%}{%endblock%} +{%block main_foot%} +
+– – +
+ + +{%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/ishtar_common/templates/ishtar/sheet.html b/ishtar_common/templates/ishtar/sheet.html new file mode 100644 index 000000000..5608a684f --- /dev/null +++ b/ishtar_common/templates/ishtar/sheet.html @@ -0,0 +1,30 @@ +{% load i18n %} +{% block main_head %} + + + + {% block title %}Ishtar{% if APP_NAME %} - {{APP_NAME}}{%endif%}{% endblock %} + + {% block css_head %} + + {% endblock %} + + +{% endblock %} +
+{% block head_sheet %} + +{% endblock %} +
+{% block content %}{% endblock %} +
+
+{%block main_foot%} + + +{%endblock%} diff --git a/ishtar_common/templates/sheet.html b/ishtar_common/templates/sheet.html deleted file mode 100644 index 5608a684f..000000000 --- a/ishtar_common/templates/sheet.html +++ /dev/null @@ -1,30 +0,0 @@ -{% load i18n %} -{% block main_head %} - - - - {% block title %}Ishtar{% if APP_NAME %} - {{APP_NAME}}{%endif%}{% endblock %} - - {% block css_head %} - - {% endblock %} - - -{% endblock %} -
-{% block head_sheet %} - -{% endblock %} -
-{% block content %}{% endblock %} -
-
-{%block main_foot%} - - -{%endblock%} diff --git a/ishtar_common/templates/sheet_contextrecord.html b/ishtar_common/templates/sheet_contextrecord.html deleted file mode 100644 index 806b06288..000000000 --- a/ishtar_common/templates/sheet_contextrecord.html +++ /dev/null @@ -1,135 +0,0 @@ -{% extends "sheet.html" %} -{% load i18n %} -{% block content %} - - -

{% trans "Context Record"%}

- -{% if item.operation.code_patriarche %} -

-{% else %} -

-

-{%endif%} -{{item.full_label}}

-{%if item.unit %} -

{{ item.unit }}

-{%endif%} -

{{ item.datings.all|join:", " }}

-

{{ item.parcel.town }}

-

{{ item.parcel.short_label }}

- -{% if item.description or item.lenght or item.width or item.depth %} -

{% trans "Description"%}

- -

{{ item.description }}

-{% if item.lenght %}

{{ item.length }}

{%endif%} -{% if item.width %}

{{ item.width }}

{%endif%} -{% if item.depth %}

{{ item.depth }}

{%endif%} -{% endif %} - -{% if item.activity or item.identification or item.interpretation %} -

{% trans "Interpretation"%}

- -{% if item.activity %}

{{ item.activity }}

{%endif%} -{% if item.identification %}

{{ item.identification }}

{%endif%} -{% if item.interpretation %}

{{ item.interpretation }}

{%endif%} -{% endif %} - -{% if item.taq or item.taq_estimated or item.tpq or item.tpq_estimated %} -

{% trans "Datations"%}

-{% if item.taq %}

{{ item.taq }}

{%endif%} -{% if item.taq_estimated %}

{{ item.taq_estimated }}

{%endif%} -{% if item.tpq %}

{{ item.tpq }}

{%endif%} -{% if item.tpq_estimated %}

{{ item.tpq_estimated }}

{%endif%} -{%endif%} - -{% if item.operation %} -

{% trans "Operation resume"%}

-

{{ item.operation.year }}

-

{{ item.operation.operation_code }}

-{% if item.operation.code_patriarche %} -

-{{ item.operation.code_patriarche }}

-{% else %}

-{%endif%} -{#

{{ item.operation.internal_reference }}

#} -

-{{ item.operation.in_charge.full_label }}

-

-{% if item.operation.is_active %} -{%trans "Active file"%}

-{% else %} -{%trans "Closed operation"%}

-

{{ item.operation.closing.date }} -{%trans "by" %} {{ item.operation.closing.user }}

-{% endif %} -

{{ item.operation.operation_type }}

-

{{ item.operation.remains.all|join:", " }}

-

{{ item.operation.periods.all|join:", " }}

-{% if item.operation.comment %}

{{ item.operation.comment }}

{%endif%} -

{% trans "Localisation"%}

-

{{ item.operation.towns.all|join:", " }}

-

-{{ item.operation }}

-{# TODO: Displayed as Year/index/Commune/Common_name This should be a link to the file sheet of the related operation #} -{% else %}

-{% endif %} - - - - - - - - {##} - - {% for doc in item.source.all %} - - - - - {##} - - {% empty %} - - {% endfor %} -
{%trans "Documents"%}
{% trans "Title" %}{% trans "Type" %}{% trans "Authors" %}{% trans "Localisation" %}
{{ doc.title }}{{doc.source_type}}{{ doc.authors.all|join:", " }}{{ doc.localisation }}
{% trans "No document associated to this context record" %}
- - - - - - - - - - - - - - - {% for find in item.base_finds.all %} - - -{# Displayed as (Patriarche operation code)-(Record unit label)-(Finds label). #} -{# or displayed as (Year)-(index)-(Record unit label)-(Finds label). #} - -{# Displayed as (Patriarche operation code)-(Record unit label)-(material code)-(Finds label indexed by material type). #} -{# or displayed as (Year)-(index)-(Record unit label)-(material code)-(Finds label indexed by material type) #} - - - {# TODO .all|join:", " ? #} - - - - - - {#{%trans "Details"%}#} - - {% empty %} - - {% endfor %} -
{%trans "Finds"%}
{% trans "Find" %}{% trans "Material type" %}{% trans "Context record" %}{% trans "Periods" %}{% trans "Description" %}{% trans "Weight" %}{% trans "Numbers" %}{% trans "Parcel" %} 
{{ find.full_label }}{{ find.material_type_label }}{{find.context_record}}{{ find.get_last_find.dating}}{{ find.get_last_find.description }}{{ find.get_last_find.weight }}{{ find.get_last_find.item_number }}{{ item.context_record.parcel.short_label }}
{% trans "No find associated to this context record" %}
- -{% endblock %} diff --git a/ishtar_common/templates/sheet_contextrecord_window.html b/ishtar_common/templates/sheet_contextrecord_window.html deleted file mode 100644 index 7ff65d1e7..000000000 --- a/ishtar_common/templates/sheet_contextrecord_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "sheet_contextrecord.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/ishtar_common/templates/sheet_file.html b/ishtar_common/templates/sheet_file.html deleted file mode 100644 index 88ef1b3a2..000000000 --- a/ishtar_common/templates/sheet_file.html +++ /dev/null @@ -1,132 +0,0 @@ -{% extends "sheet.html" %} -{% load i18n %} -{% block content %} -{% if previous or next %} -
-{%if previous%} -{%trans "Previous version"%} ({{previous}}) -{% endif %} -{% if previous and next %} - {% endif %} -{%if next%} -Rollback - -{%trans "Next version"%} ({{next}}) -{% endif %} -
-{% endif %} - -

{% trans "General"%}

-

{{ item.year }}

-

{{ item.numeric_reference }}

- -

{{ item.internal_reference }}

- -

{{ item.history_date }}

-{% if item.reception_date %}

{{ item.reception_date }}

{% endif %} -

{{ item.creation_date }}

-{% comment %} -{% if item.deadline_date and not item.acts %} -

{% item.deadline_date %}

-{% endif %} -{% endcomment %} - -

{{ item.in_charge.full_label }}

-

{% if item.is_active %}{%trans "Active file"%}

-{% else %}{%trans "Closed file"%}

-

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

-{% endif %} - -

{{ item.file_type }}

- -{% if item.related_file %}

{{ item.related_file }}

{% endif %} -{% if item.comment %}

{{ item.comment }}

{%endif%} - -

{% trans "Localisation"%}

-

{{ item.towns.all|join:", " }}

- -

{{ item.address }}

-{% if item.address_complement %}

{{ item.address_complement }}

{%endif%} -{% if item.postal_code %}

{{ item.postal_code }}

{%endif%} - -

{% if item.total_surface %} {{ item.total_surface }} m2 ({{ item.total_surface_ha }} ha){%endif%}

- - - -{% if item.is_preventive %} -

{% trans "Preventive archaelogical file"%}

-

{{ item.total_developed_surface }} m2 ({{ item.total_developed_surface_ha }} ha)

-

{{ item.saisine_type }}

-{% if item.town_planning_service %}

{{ item.town_planning_service }}

{% endif %} -{% if item.permit_type %}

{{ item.permit_type }}

{% endif %} -{% if item.permit_reference %}

{{ item.permit_reference }}

{% endif %} -{% if item.general_contractor.attached_to %}

{{ item.general_contractor.attached_to }}

{% endif %} -{% if item.general_contractor %}

{{ item.general_contractor.full_label }}

{% endif %} -{% endif %} - - - - - - - - - - {% for act in item.administrative_act.all %} - - - - - - - {% empty %} - - {% endfor %} -
{%trans "Admninistrative acts"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No administrative act associated to this archaelogical file" %}
- - - - - - - - - - - - - - {% for operation in item.operations.all %} - - - - - - - - - - - {% empty %} - - {% endfor %} -
{%trans "Associated operations"%}
{% trans "Year" %}{% trans "Reference" %}Code Patriarche{% trans "Type" %}{% trans "In charge" %}{% trans "Start date" %}{% trans "Excavation end date" %} 
{{operation.year}}{{operation.operation_code}}{{operation.code_patriarche|default:""}}{{operation.operation_type}}{{operation.in_charge|default:""}}{{operation.start_date|default:""}}{{operation.excavation_end_date|default:""}}
{% trans "No operation associated to this archaelogical file" %}
- - - - - - - - - - {% for act in item.operation_acts %} - - - - - - - {% empty %} - - {% endfor %} -
{%trans "Admninistrative acts linked to associated operations"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No administrative act linked to operations" %}
-{% endblock %} diff --git a/ishtar_common/templates/sheet_file_pdf.html b/ishtar_common/templates/sheet_file_pdf.html deleted file mode 100644 index 3c77c75f8..000000000 --- a/ishtar_common/templates/sheet_file_pdf.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "sheet_file.html" %} -{% block css_head %} - -{% endblock %} -{% block main_head %} -{{ block.super }} -
-Ishtar – {{APP_NAME}} – {{item}} -
-{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -
-– – -
- - -{%endblock%} diff --git a/ishtar_common/templates/sheet_file_window.html b/ishtar_common/templates/sheet_file_window.html deleted file mode 100644 index e9debdd0d..000000000 --- a/ishtar_common/templates/sheet_file_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "sheet_file.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/ishtar_common/templates/sheet_operation.html b/ishtar_common/templates/sheet_operation.html deleted file mode 100644 index 7b161f641..000000000 --- a/ishtar_common/templates/sheet_operation.html +++ /dev/null @@ -1,183 +0,0 @@ -{% extends "sheet.html" %} -{% load i18n %} -{% block content %} - -

{% trans "General"%}

-

{{ item.year }}

-{% if item.operation.operation_code %}

{{ item.operation_code }}

{% endif %} - -{% if item.code_patriarche %}

{{ item.code_patriarche }}

{%else%} -

{%trans "Patriarche OA code not yet recorded!"%}

{%endif%} - -{#

{{ item.internal_reference }}

#} - -

{{ item.history.all.0.history_date }}

- -{% if item.start_date %}

{{ item.start_date }}

-

{{ item.excavation_end_date|default:"-" }}

-{%endif%} -{% if item.in_charge %}

{{ item.in_charge.full_label }}

{%endif%} -

{% if item.is_active %}{%trans "Active file"%}

-{% else %}{%trans "Closed operation"%}

-

{{ item.closing.date }} {%trans "by" %} {{ item.closing.user }}

-{% endif %} -

{{ item.operation_type }}

-{% if item.surface %}

{{ item.surface }} m2 ({{ item.surface_ha }} ha)

{% endif %} -{% if item.cost %}

{{ item.cost }} €{% if item.cost_by_m2 %}, ({{ item.cost_by_m2 }} €/m2){%endif%}

{%endif%} -{% if item.duration %}

{{ item.duration }} {%trans "Day"%}s

{%endif%} - -

{{ item.remains.all|join:", " }}

-

{{ item.periods.all|join:", " }}

- -{% if item.associated_file %} -

{{ item.associated_file }}

-{% if item.associated_file.is_preventive %} -{#{% if item.operator_reference_code %}

{{ item.operator_reference_code }}

{% endif %}#} -{% if item.associated_file.town_planning_service %}

{{ item.associated_file.town_planning_service }}

{% endif %} -{% if item.associated_file.permit_type %}

{{ item.associated_file.permit_type }}

{% endif %} -{% if item.associated_file.permit_reference %}

{{ item.associated_file.permit_reference }}

{% endif %} -{% if item.associated_file.general_contractor.attached_to %}

{{ item.associated_file.general_contractor.attached_to }}

{% endif %} -{% if item.associated_file.general_contractor %}

{{ item.associated_file.general_contractor.full_label }}

{% endif %} -{% endif %} -{% endif %} - -{% if item.comment %}

{{ item.comment }}

{%endif%} - -

{% trans "Localisation"%}

-

{{ item.towns.all|join:", " }}

- -

{{ item.associated_file.address }}

-{% if item.associated_file.address_complement %}

{{ item.associated_file.address_complement }}

{%endif%} -{% if item.associated_file.postal_code %}

{{ item.associated_file.postal_code }}

{%endif%} - -{% comment %} -

{{ item.lambert_x }}

-

{{ item.lambert_y }}

-

{{ item.altitude }}

-{% endcomment %} - - - - - - - - {##} - - {% for parcel in item.parcels.all %} - - - - - - {##} - - {% empty %} - - {% endfor %} -
{%trans "Associated parcels"%}
{% trans "Commune" %}{% trans "Year" %}{% trans "Section" %}{% trans "Parcel" %}{% trans "Owner" %}
{{parcel.town}}{{parcel.year}}{{parcel.section}}{{parcel.parcel_number}}{{operation.parcel.owner}}
{% trans "No parcel associated to this operation" %}
- - - - - - - - - - {% for act in item.administrative_act.all %} - - - - - - - {% empty %} - - {% endfor %} -
{%trans "Admninistrative acts"%}
{% trans "Year" %}{% trans "Reference" %}{% trans "Type" %}{% trans "Date" %}
{{act.signature_date.year}}{{act.ref_sra}}{{act.act_type}}{{act.signature_date}}
{% trans "No acts associated to this operation" %}
- -

{% trans "Scientific documentation"%}

- - - - - - - {##} - - {% for doc in item.source.all %} - - - - - {##} - - {% empty %} - - {% endfor %} -
{%trans "Documents"%}
{% trans "Title" %}{% trans "Type" %}{% trans "Authors" %}{% trans "Localisation" %}
{{ doc.title }}{{doc.source_type}}{{ doc.authors.all|join:", " }}{{ doc.localisation }}
{% trans "No scientific document associated to this operation" %}
- - - - - - - - - - - - {% for context_record in item.context_record.all %} - - - - {# periods ?#} - - - - - {% empty %} - - {% endfor %} -
{%trans "Context records"%}
{% trans "ID" %}{% trans "Type" %}{% trans "Chronology" %}{% trans "Description" %}{% trans "Parcel" %} 
{{ context_record.label }}{{context_record.unit|default:""}}{{ context_record.datings.all|join:", " }}{{ context_record.description }}{{ context_record.parcel.section }} - {{context_record.parcel.parcel_number}}
{% trans "No context record associated to this operation" %}
-
- - - - - - - - - - - - - - {% for context_record in item.context_record.all %} - {% for find in context_record.base_finds.all %} - - -{# Displayed as (Patriarche operation code)-(Record unit label)-(Finds label). #} -{# or displayed as (Year)-(index)-(Record unit label)-(Finds label). #} - - - {# TODO .all|join:", " ? #} - - - - - - {#{%trans "Details"%}#} - - {% empty %} - - {% endfor %} - {% empty %} - - {% endfor %} -
{%trans "Finds"%}
{% trans "Find" %}{% trans "Material type" %}{% trans "Context record" %}{% trans "Periods" %}{% trans "Description" %}{% trans "Weight" %}{% trans "Numbers" %}{% trans "Parcel" %} 
{{ find.full_label }}{{ find.material_type_label }}{{find.context_record.label}}{{ find.get_last_find.dating}}{{ find.get_last_find.description }}{{ find.get_last_find.weight }}{{ find.get_last_find.item_number }}{{ context_record.parcel.short_label }}
{% trans "No find associated to context record" %} {{context_record.short_label}}
{% trans "No find associated to parcel" %} {{parcel.short_label}} {% trans "(no context record)" %}
-
- -{% endblock %} diff --git a/ishtar_common/templates/sheet_operation_pdf.html b/ishtar_common/templates/sheet_operation_pdf.html deleted file mode 100644 index 3397d5f43..000000000 --- a/ishtar_common/templates/sheet_operation_pdf.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "sheet_operation.html" %} -{% block css_head %} - -{% endblock %} -{% block main_head %} -{{ block.super }} -
-Ishtar – {{APP_NAME}} – {{item}} -
-{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -
-– – -
- - -{%endblock%} diff --git a/ishtar_common/templates/sheet_operation_window.html b/ishtar_common/templates/sheet_operation_window.html deleted file mode 100644 index 9c595a1e9..000000000 --- a/ishtar_common/templates/sheet_operation_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "sheet_operation.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 54523996f..0d0168bb9 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -384,7 +384,7 @@ def show_item(model, name): n.strftime('%Y%m%d-%H%M%S')) if doc_type == "odt" and settings.XHTML2ODT_PATH and \ settings.ODT_TEMPLATE: - tpl = loader.get_template('sheet_%s.html' % name) + tpl = loader.get_template('ishtar/sheet_%s.html' % name) content = tpl.render(context_instance) try: tidy_options = dict(output_xhtml=1, add_xml_decl=1, indent=1, @@ -424,7 +424,7 @@ def show_item(model, name): response.write(odtfile) return response elif doc_type == 'pdf': - tpl = loader.get_template('sheet_%s_pdf.html' % name) + tpl = loader.get_template('ishtar/sheet_%s_pdf.html' % name) content = tpl.render(context_instance) result = StringIO.StringIO() html = content.encode('utf-8') @@ -438,7 +438,7 @@ def show_item(model, name): return response return HttpResponse(content, content_type="application/xhtml") else: - tpl = loader.get_template('sheet_%s_window.html' % name) + tpl = loader.get_template('ishtar/sheet_%s_window.html' % name) content = tpl.render(context_instance) return HttpResponse(content, content_type="application/xhtml") return func -- cgit v1.2.3 From 38f7e9685df66772253a4eb1cd6d53a9d461a937 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 18:48:14 +0200 Subject: Operation sheet: group parcels by sections - add parcels to File sheet (refs #1193) --- archaeological_files/models.py | 6 +++++- .../templates/ishtar/sheet_file.html | 22 ++++++++++++++++++++++ archaeological_operations/models.py | 21 ++++++++++++++++++++- .../templates/ishtar/sheet_operation.html | 8 ++++---- archaeological_operations/views.py | 2 +- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/archaeological_files/models.py b/archaeological_files/models.py index a91f6ed69..1e2c36ed0 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 Étienne Loks +# Copyright (C) 2012-2013 É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 @@ -133,6 +133,10 @@ class File(BaseHistorizedItem, OwnPerms): for k in ['internal_reference',] if getattr(self, k)] return settings.JOINT.join(items) + def grouped_parcels(self): + from archaeological_operations.models import Parcel + return Parcel.grouped_parcels(list(self.parcels.all())) + @classmethod def get_query_owns(cls, user): return Q(history_modifier=user) & Q(end_date__isnull=True) diff --git a/archaeological_files/templates/ishtar/sheet_file.html b/archaeological_files/templates/ishtar/sheet_file.html index 1b58aa332..bdf0bd4ff 100644 --- a/archaeological_files/templates/ishtar/sheet_file.html +++ b/archaeological_files/templates/ishtar/sheet_file.html @@ -62,6 +62,28 @@ {% if item.general_contractor %}

{{ item.general_contractor.full_label }}

{% endif %} {% endif %} + + + + + + + + {##} + + {% for parcel in item.grouped_parcels %} + + + + + + {##} + + {% empty %} + + {% endfor %} +
{%trans "Associated parcels"%}
{% trans "Commune" %}{% trans "Year" %}{% trans "Section" %}{% trans "Parcels" %}{% trans "Owner" %}
{{parcel.town}}{{parcel.year}}{{parcel.section}}{{parcel.parcel_numbers|join:", "}}{{operation.parcel.owner}}
{% trans "No parcel associated to this operation" %}
+ diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 675666dbb..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 +# Copyright (C) 2012-2013 É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 @@ -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: @@ -328,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 index 1698f0224..491304125 100644 --- a/archaeological_operations/templates/ishtar/sheet_operation.html +++ b/archaeological_operations/templates/ishtar/sheet_operation.html @@ -61,15 +61,15 @@ - + {##} - {% for parcel in item.parcels.all %} + {% for parcel in item.grouped_parcels %} - + {##} {% empty %} @@ -78,7 +78,7 @@
{%trans "Admninistrative acts"%}
{% trans "Commune" %} {% trans "Year" %} {% trans "Section" %}{% trans "Parcel" %}{% trans "Parcels" %}{% trans "Owner" %}
{{parcel.town}} {{parcel.year}} {{parcel.section}}{{parcel.parcel_number}}{{parcel.parcel_numbers|join:", "}}{{operation.parcel.owner}}
- + diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 84f208bf3..6e570fc97 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 +# Copyright (C) 2010-2013 É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 -- cgit v1.2.3 From 7057a537f4f28d80379500ab2e9c4d078bb01682 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 18:59:15 +0200 Subject: Fix main dashboard (refs #1040) --- ishtar_common/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index e5d966bf9..fd5bb5871 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -451,6 +451,7 @@ class Dashboard: operation_mode_pk = self.get_mode(dict(zip(operations, operation_numbers))) if operation_mode_pk: + from archaeological_operations.models import Operation self.operation_mode = unicode(Operation.objects.get( pk=operation_mode_pk)) -- cgit v1.2.3 From ed54f33ef281d886b45c47f1ef491aeaa4785756 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 19:07:19 +0200 Subject: Fix finds display --- archaeological_finds/models.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py index a02cb4402..ce0df10cf 100644 --- a/archaeological_finds/models.py +++ b/archaeological_finds/models.py @@ -82,7 +82,9 @@ class BaseFind(BaseHistorizedItem, OwnPerms): return settings.JOINT.join(finds) def _real_label(self): - if not self.context_record.parcel.operation.code_patriarche: + if not self.context_record.parcel \ + or not self.context_record.parcel.operation \ + or not self.context_record.parcel.operation.code_patriarche: return find = self.get_last_find() lbl = find.label or self.label @@ -92,7 +94,9 @@ class BaseFind(BaseHistorizedItem, OwnPerms): lbl) if it]) def _temp_label(self): - if self.context_record.parcel.operation.code_patriarche: + if not self.context_record.parcel \ + or not self.context_record.parcel.operation \ + or not self.context_record.parcel.operation.code_patriarche: return find = self.get_last_find() lbl = find.label or self.label -- cgit v1.2.3 From 479de494ac3f154c4e77b89b6daa700d473b260a Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 19:25:13 +0200 Subject: Fix duplicate parcel test (refs #1162) --- archaeological_operations/forms.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 547daf828..66bd05b4b 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -96,8 +96,9 @@ class ParcelForm(forms.Form): class ParcelFormSet(FormSet): 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) -- cgit v1.2.3 From e121fde541630e72888a3314f50c3ac0fb88186d Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 19:37:01 +0200 Subject: Operation: search by period (refs #1017) --- archaeological_operations/forms.py | 2 ++ archaeological_operations/views.py | 8 -------- ishtar_common/views.py | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 66bd05b4b..0318d4207 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -122,6 +122,8 @@ class OperationSelect(TableSelect): 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) diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 6e570fc97..1ce4c4622 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -92,14 +92,6 @@ def get_available_operation_code(request, year=None): data = json.dumps({'id':models.Operation.get_available_operation_code(year)}) return HttpResponse(data, mimetype='text/plain') -def get_parcel_parser(key_section, key_number): - def func(dct): - print dct - section, number = dct.get(key_section), dct.get(key_number) - if not section or not number: - return {} - return {key_section:section, key_number:number} - get_operation = get_item(models.Operation, 'get_operation', 'operation', bool_fields = ['end_date__isnull'], dated_fields = ['start_date__lte', 'start_date__gte', diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 0d0168bb9..641ca8046 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -170,7 +170,7 @@ def format_val(val): return unicode(val) HIERARCHIC_LEVELS = 5 -HIERARCHIC_FIELDS = ['period', 'unit', 'material_type'] +HIERARCHIC_FIELDS = ['periods', 'period', 'unit', 'material_type'] PRIVATE_FIELDS = ('id', 'history_modifier', 'order') def get_item(model, func_name, default_name, extra_request_keys=[], base_request={}, bool_fields=[], dated_fields=[]): -- cgit v1.2.3 From c5e94062adefdd8cb0aeb730830921d5d546a86b Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 4 Apr 2013 20:49:29 +0200 Subject: Inline formset to manage parcels --- archaeological_operations/forms.py | 8 +++++-- archaeological_operations/wizards.py | 5 +++- ishtar_common/static/media/style.css | 13 ++++++++++ ishtar_common/templates/blocks/form_snippet.html | 13 ++++++++++ ishtar_common/templates/blocks/inline_formset.html | 25 +++++++++++++++++++ ishtar_common/templates/form_snippet.html | 13 ---------- .../templates/ishtar/wizard/default_wizard.html | 4 ++++ .../templates/ishtar/wizard/parcels_wizard.html | 28 ++++++++++++++++++++++ .../templates/ishtar/wizard/towns_wizard.html | 10 +------- ishtar_common/templatetags/inline_formset.py | 18 ++++++++++++++ ishtar_common/templatetags/table_form.py | 2 +- 11 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 ishtar_common/templates/blocks/form_snippet.html create mode 100644 ishtar_common/templates/blocks/inline_formset.html delete mode 100644 ishtar_common/templates/form_snippet.html create mode 100644 ishtar_common/templates/ishtar/wizard/parcels_wizard.html create mode 100644 ishtar_common/templatetags/inline_formset.py diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 0318d4207..741dfb2b7 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -37,8 +37,9 @@ 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, TableSelect +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 @@ -94,6 +95,9 @@ 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', 'section', diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index 3281a5723..2b13e3353 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -34,9 +34,12 @@ class OperationWizard(Wizard): 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 + 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): diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css index cad9a224a..fe078fa3c 100644 --- a/ishtar_common/static/media/style.css +++ b/ishtar_common/static/media/style.css @@ -528,6 +528,19 @@ a.remove{ border:1px solid; } +.form table.inline-table th{ + text-align:center; + font-weight:bold; +} + +.form table.inline-table td{ + text-align:center; +} + +.inline-table input[type=text]{ + width:60px; +} + .widget-parcel{ width:60px; } diff --git a/ishtar_common/templates/blocks/form_snippet.html b/ishtar_common/templates/blocks/form_snippet.html new file mode 100644 index 000000000..2f841e078 --- /dev/null +++ b/ishtar_common/templates/blocks/form_snippet.html @@ -0,0 +1,13 @@ +{% load i18n %} + {% if form.non_field_errors %} + + {%endif%} + {% for field in form %}{% if not field.is_hidden %} + + + {% if field.help_text %} + + + + + {%endif%}{% else %}{{field}}{% endif %}{% endfor %} diff --git a/ishtar_common/templates/blocks/inline_formset.html b/ishtar_common/templates/blocks/inline_formset.html new file mode 100644 index 000000000..e36405118 --- /dev/null +++ b/ishtar_common/templates/blocks/inline_formset.html @@ -0,0 +1,25 @@ +{% load i18n %} + {% if extra_formset.non_form_errors %}
{{extra_formset.non_form_errors.as_ul}}
{% endif %} + {% if header %}
{%trans "Admninistrative acts"%}{%trans "Administrative acts"%}
{% trans "Year" %} {% trans "Reference" %}
{{form.non_field_errors}}
{{ field.label_tag }} {{ field.errors }}{{field|safe}}?
{{field.help_text}}
+ + {% endif %}{% for frm in formset%}{% if header %} + {% for field in frm.visible_fields%} + {%endfor%} + + {% endif %} + {% if forloop.first and not skip %}{%endif%} + {% if not skip or not forloop.first %}{% endif %}{% for field in frm.visible_fields %} + {% endfor %} + {% if not skip or not forloop.last %}{% endif %}{%endfor%} + {% if not skip %}{% endif %}{% if header %} +
{% trans caption %}
{{field.label}}
+ {% if field.errors %}
{{ field.errors.as_ul }}
{% endif %} + {{ field }} + {# Include the hidden fields in the form #} + {% if forloop.first %} + {{ formset.management_form }} + {% for hidden in frm.hidden_fields %} + {{ hidden }} + {% endfor %} + {% endif %} +
{% endif %} diff --git a/ishtar_common/templates/form_snippet.html b/ishtar_common/templates/form_snippet.html deleted file mode 100644 index 2f841e078..000000000 --- a/ishtar_common/templates/form_snippet.html +++ /dev/null @@ -1,13 +0,0 @@ -{% load i18n %} - {% if form.non_field_errors %} - {{form.non_field_errors}} - {%endif%} - {% for field in form %}{% if not field.is_hidden %} - - {{ field.label_tag }} - {{ field.errors }}{{field|safe}}{% if field.help_text %} - ? - - -
{{field.help_text}}
- {%endif%}{% else %}{{field}}{% endif %}{% endfor %} diff --git a/ishtar_common/templates/ishtar/wizard/default_wizard.html b/ishtar_common/templates/ishtar/wizard/default_wizard.html index e2abc80b6..b56324a78 100644 --- a/ishtar_common/templates/ishtar/wizard/default_wizard.html +++ b/ishtar_common/templates/ishtar/wizard/default_wizard.html @@ -6,6 +6,7 @@ {{form.media}} {% endblock %} {% block content %} +{% block wizard_head %}

{{wizard_label}}

{% csrf_token %}
    @@ -17,6 +18,8 @@
  • » 
  • {% endfor %}
+{% endblock %} +{% block wizard_form %}
{% if reminder %}
{{ reminder }}
{%endif%} {{ wizard.form.media }} @@ -43,3 +46,4 @@
{% endblock %} +{% endblock %} diff --git a/ishtar_common/templates/ishtar/wizard/parcels_wizard.html b/ishtar_common/templates/ishtar/wizard/parcels_wizard.html new file mode 100644 index 000000000..94e9820ab --- /dev/null +++ b/ishtar_common/templates/ishtar/wizard/parcels_wizard.html @@ -0,0 +1,28 @@ +{% extends "ishtar/wizard/default_wizard.html" %} +{% load i18n range inline_formset %} +{% block extra_head %} +{{wizard.form.media}} +{% endblock %} +{% block wizard_form %} +
+{% if reminder %}
{{ reminder }}
{%endif%} +{{ wizard.form.media }} +{{ wizard.management_form }} + {{ wizard.form.management_form }} +
+ {%if wizard.form.non_form_errors%} + + +
{{wizard.form.non_form_errors}}
{%endif%} + + {% for field in wizard.form.forms.0 %}{% endfor %} + {% inline_formset 'Parcels' wizard.form.forms False %} +
{{ field.label_tag }}
+

+ +{{ previous_fields|safe }} + +{% if next_steps %}{% endif %} +
+ +{% endblock %} diff --git a/ishtar_common/templates/ishtar/wizard/towns_wizard.html b/ishtar_common/templates/ishtar/wizard/towns_wizard.html index cd40e6049..cc3487df3 100644 --- a/ishtar_common/templates/ishtar/wizard/towns_wizard.html +++ b/ishtar_common/templates/ishtar/wizard/towns_wizard.html @@ -4,15 +4,7 @@ {% block extra_head %} {{wizard.form.media}} {% endblock %} -{% block content %} -

{{wizard_label}}

-
{% csrf_token %} - +{% block wizard_form %}
{% if TOWNS %} {% if wizard.form.forms %} diff --git a/ishtar_common/templatetags/inline_formset.py b/ishtar_common/templatetags/inline_formset.py new file mode 100644 index 000000000..c3220f207 --- /dev/null +++ b/ishtar_common/templatetags/inline_formset.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from django import template +from django.utils.translation import ugettext as _ +import re + +register = template.Library() + +@register.inclusion_tag('blocks/inline_formset.html') +def inline_formset(caption, formset, header=True, skip=False): + u""" + Render a formset as an inline table. + For i18n of the caption be carreful to add manualy the caption label to + the translated fields + """ + return {'caption':caption, 'formset':formset, 'header':header, 'skip':skip} + diff --git a/ishtar_common/templatetags/table_form.py b/ishtar_common/templatetags/table_form.py index 7adb54d65..0ab49d93f 100644 --- a/ishtar_common/templatetags/table_form.py +++ b/ishtar_common/templatetags/table_form.py @@ -5,6 +5,6 @@ from django.template import Library register = Library() -@register.inclusion_tag('form_snippet.html') +@register.inclusion_tag('blocks/form_snippet.html') def table_form(form): return {'form': form} -- cgit v1.2.3 From e51684c2adb656d3ef14e40e649e280a6c0bf1b8 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 5 Apr 2013 00:33:07 +0200 Subject: UI improvment for parcels management (refs #151) --- archaeological_files/wizards.py | 8 +++++--- archaeological_operations/forms.py | 12 +++++++----- archaeological_operations/wizards.py | 36 +++++++++++++++++++++++++++++++++--- ishtar_common/widgets.py | 2 +- ishtar_common/wizards.py | 21 ++++++++++++++++----- 5 files changed, 62 insertions(+), 17 deletions(-) diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py index e2f6722ef..c475de47d 100644 --- a/archaeological_files/wizards.py +++ b/archaeological_files/wizards.py @@ -25,16 +25,18 @@ from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from ishtar_common.wizards import Wizard, ClosingWizard -from archaeological_operations.wizards import OperationAdministrativeActWizard,\ +from archaeological_operations.wizards import OperationWizard,\ + OperationAdministrativeActWizard,\ AdministrativeActDeletionWizard from ishtar_common.models import Town from archaeological_operations.models import AdministrativeAct, Parcel, \ Operation import models -class FileWizard(Wizard): +class FileWizard(OperationWizard): model = models.File object_parcel_type = 'associated_file' + parcel_step_key = 'parcels-' def get_form(self, step=None, data=None, files=None): """ @@ -103,7 +105,7 @@ class FileWizard(Wizard): continue try: dct['town'] = models.Town.objects.get(pk=int(dct['town'])) - except (ValueError, ObjectDoesNotExist): + except (ValueError, ObjectDoesNotExist, KeyError): continue dct['associated_file'], dct['operation'] = None, None dct[self.object_parcel_type] = obj diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 741dfb2b7..72834d8f0 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -59,13 +59,13 @@ class ParcelForm(forms.Form): 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']: @@ -85,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 " diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index 2b13e3353..4205144e6 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -27,16 +27,19 @@ 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 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 @@ -124,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: @@ -133,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 @@ -148,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 diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 1fd0b6ac0..06d6f20f0 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -206,7 +206,7 @@ class JQueryJqGrid(forms.RadioSelect): self.source_full = source_full def render(self, name, value=None, attrs=None): - t = loader.get_template('form_snippet.html') + t = loader.get_template('blocks/form_snippet.html') rendered = t.render(Context({'form':self.form})) rendered += u"\n\n"\ u"" % ( diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 8b6e1a50d..e421c25dd 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2012 Étienne Loks +# Copyright (C) 2010-2013 É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 @@ -461,15 +461,26 @@ class Wizard(NamedUrlWizardView): k = u'-'.join(items) data[k] = data.pop(key)[0] # get a form key - base_key = form.form.base_fields.keys()[0] - init = self.get_form_initial(step) + frm = form.form + if callable(frm): + frm = frm() + base_key = frm.base_fields.keys()[-1] + init = self.get_form_initial(step, data=data) total_field = len([key for key in data.keys() if base_key in key.split('-') and data[key]]) - if init and not to_delete: + if init and not to_delete and ( + not hasattr(self, 'form_initialized') or + not self.form_initialized): total_field = max((total_field, len(init))) data[step + u'-INITIAL_FORMS'] = unicode(total_field) data[step + u'-TOTAL_FORMS'] = unicode(total_field + 1) + # update initialization + if request.POST and init and hasattr(self, 'form_initialized') \ + and self.form_initialized: + for k in init[0]: + data[step + '-' + unicode(total_field) + '-' + k] = \ + init[0][k] data = data or None form = super(Wizard, self).get_form(step, data, files) return form @@ -561,7 +572,7 @@ class Wizard(NamedUrlWizardView): pass return current_obj - def get_form_initial(self, step): + def get_form_initial(self, step, data=None): current_obj = self.get_current_object() current_step = self.steps.current request = self.request -- cgit v1.2.3