summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2013-04-04 14:58:05 +0200
committerÉtienne Loks <etienne.loks@peacefrogs.net>2013-04-04 17:27:54 +0200
commit8e19be1b27cf14cf0f76d7c4bcd81e520ac95407 (patch)
tree388ccdce5f40fe3bda8c457daeb397805925526d
parent3f6567507978281761005dc12951511e0c81a9ae (diff)
downloadIshtar-8e19be1b27cf14cf0f76d7c4bcd81e520ac95407.tar.bz2
Ishtar-8e19be1b27cf14cf0f76d7c4bcd81e520ac95407.zip
Forms (operations, context records, files): add search by parcel (refs #575)
-rw-r--r--archaeological_context_records/forms.py16
-rw-r--r--archaeological_context_records/views.py7
-rw-r--r--archaeological_files/forms.py17
-rw-r--r--archaeological_files/views.py8
-rw-r--r--archaeological_finds/forms.py4
-rw-r--r--archaeological_operations/forms.py24
-rw-r--r--archaeological_operations/views.py14
-rw-r--r--archaeological_operations/widgets.py43
-rw-r--r--archaeological_warehouse/forms.py5
-rw-r--r--ishtar_common/forms.py6
-rw-r--r--ishtar_common/forms_common.py4
-rw-r--r--ishtar_common/static/media/style.css3
-rw-r--r--ishtar_common/views.py2
-rw-r--r--ishtar_common/widgets.py6
14 files changed, 132 insertions, 27 deletions
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 <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
@@ -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 <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,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 <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
@@ -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 <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_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 <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
@@ -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"<p>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<h4>%s</h4>\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&amp;" + data;
+ var url = "%(source)s?submited=1&" + data;
mygrid.setGridParam({url:url});
mygrid.trigger("reloadGrid");
return false;