summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2011-03-06 22:49:08 +0100
committerÉtienne Loks <etienne.loks@peacefrogs.net>2011-03-06 22:49:08 +0100
commitb467050d3f65830e175f4a1483db11e0c603aca3 (patch)
treef56549ff998890309f78b525972c9b578d016503
parent0d37af8098ed4bc7f3ffc552e8454ee897eb39c1 (diff)
downloadIshtar-b467050d3f65830e175f4a1483db11e0c603aca3.tar.bz2
Ishtar-b467050d3f65830e175f4a1483db11e0c603aca3.zip
Creation of context record (refs #18)
-rw-r--r--ishtar/furnitures/forms.py233
-rw-r--r--ishtar/furnitures/menus.py17
-rw-r--r--ishtar/furnitures/models.py19
-rw-r--r--ishtar/furnitures/urls.py2
-rw-r--r--static/media/style.css4
5 files changed, 245 insertions, 30 deletions
diff --git a/ishtar/furnitures/forms.py b/ishtar/furnitures/forms.py
index 1f2640e5c..642da9b4b 100644
--- a/ishtar/furnitures/forms.py
+++ b/ishtar/furnitures/forms.py
@@ -22,6 +22,7 @@ Forms definition
"""
import datetime
import re
+from itertools import groupby
from django.core.urlresolvers import reverse
from django.core import validators
@@ -155,7 +156,9 @@ class Wizard(NamedUrlSessionFormWizard):
continue
if form_datas:
form_datas.append(("", "", "spacer"))
- for key in cleaned_data:
+ items = hasattr(base_form, 'fields') and \
+ base_form.fields.keyOrder or cleaned_data.keys()
+ for key in items:
lbl = None
if key.startswith('hidden_'):
continue
@@ -172,8 +175,11 @@ class Wizard(NamedUrlSessionFormWizard):
elif value == False:
value = _("No")
elif key in associated_models:
- value = unicode(associated_models[key].objects.get(
- pk=value))
+ item = associated_models[key].objects.get(pk=value)
+ if hasattr(item, 'short_label'):
+ value = item.short_label()
+ else:
+ value = unicode(item)
form_datas.append((lbl, value, ''))
if form_datas:
datas.append((form.form_label, form_datas))
@@ -218,15 +224,31 @@ class Wizard(NamedUrlSessionFormWizard):
else:
value = None
dct[key] = value
+ return self.save_model(dct, m2m, request, storage, form_list,
+ return_object)
+
+ def get_saved_model(self):
+ """
+ Permit a distinguo when saved model is not the base selected model
+ """
+ return self.model
+
+ def get_current_saved_object(self, request, storage):
+ """
+ Permit a distinguo when saved model is not the base selected model
+ """
+ return self.get_current_object(request, storage)
+
+ def save_model(self, dct, m2m, request, storage, form_list, return_object):
dct = self.get_extra_model(dct, request, storage, form_list)
- obj = self.get_current_object(request, storage)
+ obj = self.get_current_saved_object(request, storage)
if obj:
for k in dct:
if k.startswith('pk'):
continue
setattr(obj, k, dct[k])
else:
- obj = self.model(**dct)
+ obj = self.get_saved_model()(**dct)
obj.save()
for key, value in m2m:
if value not in getattr(obj, key+'s').all():
@@ -1020,35 +1042,21 @@ file_closing_wizard = FileWizard([
class FileAdministrativeActWizard(FileWizard):
edit = False
+
def get_associated_item(self, request, storage, dct):
return self.get_current_object(request, storage)
- def done(self, request, storage, form_list, **kwargs):
- '''
- Save the administrative act
- '''
- dct = {}
- for form in form_list:
- if not form.is_valid():
- return self.render(request, storage, form)
- associated_models = hasattr(form, 'associated_models') and \
- form.associated_models or {}
- if type(form.cleaned_data) == dict:
- for key in form.cleaned_data:
- if key == 'pk':
- continue
- value = form.cleaned_data[key]
- if key in associated_models and value:
- value = associated_models[key].objects.get(pk=value)
- dct[key] = value
+ def save(self, dct, m2m, request, storage, form_list, return_object):
associated_item = self.get_associated_item(request, storage, dct)
if not associated_item:
- return self.render(request, storage, form)
+ return self.render(request, storage, form_list[-1])
if isinstance(associated_item, models.File):
dct['associated_file'] = associated_item
elif isinstance(associated_item, models.Operation):
dct['operation'] = associated_item
dct['history_modifier'] = request.user
+ if 'pk' in dct:
+ dct.pop('pk')
if self.edit:
admact = self.get_current_object(request, storage)
for k in dct:
@@ -1581,3 +1589,180 @@ operation_administrativeact_deletion_wizard = AdministrativeActDeletionWizard([
('final-operation_administrativeact_deletion',
FinalAdministrativeActDeleteForm)],
url_name='operation_administrativeact_deletion',)
+
+class RecordWizard(Wizard):
+ model = models.Operation
+ edit = False
+
+ def get_form(self, request, storage, step=None, data=None, files=None):
+ """
+ Get associated operation
+ """
+ if data:
+ data = data.copy()
+ else:
+ data = {}
+ if not step:
+ step = self.determine_step(request, storage)
+ form = self.get_form_list(request, storage)[step]
+ current_object = self.get_current_object(request, storage)
+ if step.startswith('general-') and current_object:
+ data['operation'] = current_object
+ form = super(RecordWizard, self).get_form(request, storage, step, data,
+ files)
+ return form
+
+ def get_saved_model(self):
+ return models.ContextRecord
+
+ def get_current_saved_object(self, request, storage):
+ return None
+
+ def save_model(self, dct, m2m, request, storage, form_list, return_object):
+ if 'pk' in dct:
+ dct.pop('pk')
+ return super(RecordWizard, self).save_model(dct, m2m, request, storage,
+ form_list, return_object)
+
+ def done(self, request, storage, form_list, **kwargs):
+ '''
+ Save datings
+ '''
+ r = super(RecordWizard, self).done(request, storage, form_list,
+ return_object=True, **kwargs)
+ if type(r) not in (list, tuple) or len(r) != 2:
+ print 1
+ print r
+ return r
+ print 2
+ obj, res = r
+ for form in form_list:
+ if not hasattr(form, 'prefix') \
+ or not form.prefix.startswith('datings-') \
+ or not hasattr(form, 'forms'):
+ continue
+ datings = obj.datings.clear()
+ for frm in form.forms:
+ if not frm.is_valid():
+ continue
+ dct = frm.cleaned_data.copy()
+ print dct
+ if not dct:
+ continue
+ try:
+ dct['period'] = models.Period.objects.get(
+ pk=int(dct['period']))
+ except (ValueError, ObjectDoesNotExist):
+ continue
+ try:
+ dct['dating_type'] = models.DatingType.objects.get(
+ pk=int(dct['dating_type']))
+ except (ValueError, ObjectDoesNotExist):
+ continue
+ try:
+ dct['quality'] = models.DatingQuality.objects.get(
+ pk=int(dct['quality']))
+ except (ValueError, ObjectDoesNotExist):
+ continue
+ if 'DELETE' in dct:
+ dct.pop('DELETE')
+ dating = models.Dating.objects.filter(**dct).all()
+ if dating:
+ dating = dating[0]
+ else:
+ dating = models.Dating(**dct)
+ dating.save()
+ obj.datings.add(dating)
+ return res
+
+
+class RecordFormGeneral(forms.Form):
+ form_label = _("General")
+ associated_models = {'parcel':models.Parcel,}
+ parcel = forms.ChoiceField(label=_("Parcel"), choices=[('', '--')])
+ label = forms.CharField(label=_(u"Label"),
+ validators=[validators.MaxLengthValidator(200)])
+ description = forms.CharField(label=_(u"Description"),
+ widget=forms.Textarea, required=False)
+ lenght = forms.IntegerField(label=_(u"Lenght"))
+ width = forms.IntegerField(label=_(u"Width"))
+ thickness = forms.IntegerField(label=_(u"Thickness"))
+ depth = forms.IntegerField(label=_(u"Depth"))
+ location = forms.CharField(label=_(u"Location"), widget=forms.Textarea,
+ required=False, validators=[validators.MaxLengthValidator(200)])
+
+ def __init__(self, *args, **kwargs):
+ operation = None
+ if 'data' in kwargs and kwargs['data'] and \
+ 'operation' in kwargs['data']:
+ operation = kwargs['data']['operation']
+ # clean data if not "real" data
+ prefix_value = kwargs['prefix']
+ if not [k for k in kwargs['data'].keys()
+ if k.startswith(kwargs['prefix']) and kwargs['data'][k]]:
+ kwargs['data'] = None
+ if 'files' in kwargs:
+ kwargs.pop('files')
+ super(RecordFormGeneral, self).__init__(*args, **kwargs)
+ if operation and len(self.fields['parcel'].choices) == 1:
+ parcels = operation.parcels.all()
+ sort = lambda x: (x.town.name, x.section)
+ parcels = sorted(parcels, key=sort)
+ for key, gparcels in groupby(parcels, sort):
+ self.fields['parcel'].choices.append(
+ (" - ".join(key), [(parcel.pk, parcel.short_label()) for parcel in gparcels])
+ )
+
+class DatingForm(forms.Form):
+ form_label = _("Datings")
+ period = forms.ChoiceField(label=_("Period"),
+ choices=models.Period.get_types())
+ start_date = forms.IntegerField(label=_(u"Start date"))
+ end_date = forms.IntegerField(label=_(u"End date"))
+ dating_type = forms.ChoiceField(label=_("Dating type"),
+ choices=models.DatingType.get_types())
+ quality = forms.ChoiceField(label=_("Quality"),
+ choices=models.DatingQuality.get_types())
+
+DatingFormSet = formset_factory(DatingForm, can_delete=True,
+ formset=FormSet)
+DatingFormSet.form_label = _("Dating")
+
+class UnitForm(forms.Form):
+ form_label = _("Units")
+ associated_models = {'unit':models.Unit}
+ unit = forms.ChoiceField(label=_("Unit"),
+ choices=models.Unit.get_types())
+
+class UnitFormSet(FormSet):
+ def clean(self):
+ return clean_duplicated(self, ['unit'])
+
+UnitFormSet = formset_factory(UnitForm, can_delete=True,
+ formset=UnitFormSet)
+UnitFormSet.form_label = _("Unit")
+
+class RecordFormInterpretation(forms.Form):
+ form_label = _("Interpretation")
+ associated_models = {'parcel':models.Parcel,}
+ has_furniture = forms.BooleanField(label=_(u"Has furniture?"))
+ filling = forms.CharField(label=_(u"Filling"),
+ widget=forms.Textarea, required=False)
+ interpretation = forms.CharField(label=_(u"Interpretation"),
+ widget=forms.Textarea, required=False)
+ taq = forms.IntegerField(label=_(u"TAQ"), required=False)
+ taq_estimated = forms.IntegerField(label=_(u"Estimated TAQ"),
+ required=False)
+ tpq = forms.IntegerField(label=_(u"TPQ"), required=False)
+ tpq_estimated = forms.IntegerField(label=_(u"Estimated TPQ"),
+ required=False)
+
+record_creation_wizard = RecordWizard([
+ ('selec-record_creation', OperationFormSelection),
+ ('general-record_creation', RecordFormGeneral),
+ ('datings-record_creation', DatingFormSet),
+ ('units-record_creation', UnitFormSet),
+ ('interpretation-record_creation', RecordFormInterpretation),
+ ('final-record_creation', FinalForm)],
+ url_name='record_creation',)
+
diff --git a/ishtar/furnitures/menus.py b/ishtar/furnitures/menus.py
index 12c81ced3..d2fa5fba4 100644
--- a/ishtar/furnitures/menus.py
+++ b/ishtar/furnitures/menus.py
@@ -168,6 +168,23 @@ class Menu:
'delete_own_operation']),
],),
]),
+ SectionItem('record_management', _(u"Context record management"),
+ childs=[SectionItem('by_operation', _(u"By operation"),
+ childs=[
+ MenuItem('record_creation', _(u"Creation"),
+ model=models.ContextRecord,
+ access_controls=['add_contextrecord',
+ 'add_own_contextrecord']),
+ MenuItem('record_modification', _(u"Modification"),
+ model=models.ContextRecord,
+ access_controls=['change_contextrecord',
+ 'change_own_contextrecord']),
+ MenuItem('record_deletion', _(u"Deletion"),
+ model=models.ContextRecord,
+ access_controls=['delete_contextrecord',
+ 'delete_own_contextrecord']),
+ ],),
+ ])
]
self.items = {}
diff --git a/ishtar/furnitures/models.py b/ishtar/furnitures/models.py
index cea0c1b4c..c1980f68c 100644
--- a/ishtar/furnitures/models.py
+++ b/ishtar/furnitures/models.py
@@ -456,7 +456,8 @@ class Parcel(LightHistorizedItem):
null=True, verbose_name=_(u"Operation"))
year = models.IntegerField(_(u"Year"),
default=lambda:datetime.datetime.now().year)
- town = models.ForeignKey("Town", related_name='+', verbose_name=_(u"Town"))
+ town = models.ForeignKey("Town", related_name='parcels',
+ verbose_name=_(u"Town"))
section = models.CharField(_(u"Section"), max_length=4)
parcel_number = models.CharField(_(u"Parcel number"), max_length=6)
@@ -464,6 +465,11 @@ class Parcel(LightHistorizedItem):
verbose_name = _(u"Parcel")
verbose_name_plural = _(u"Parcels")
+ def short_label(self):
+ return u" - ".join([unicode(item) for item in \
+ [self.town, self.section, self.parcel_number]
+ if item])
+
def __unicode__(self):
return u" - ".join([unicode(item) for item in \
[self.associated_file, self.operation, self.section, self.parcel_number]
@@ -550,12 +556,15 @@ class ContextRecord(BaseHistorizedItem, OwnPerms):
width = models.IntegerField(_(u"Width"))
thickness = models.IntegerField(_(u"Thickness"))
depth = models.IntegerField(_(u"Depth"))
+ location = models.CharField(_(u"Location"), blank=True, null=True,
+ max_length=200,
+ help_text=_(u"A short description of the location of the context record"))
+ datings = models.ManyToManyField(Dating)
+ units = models.ManyToManyField(Unit)
has_furniture = models.BooleanField(u"Has furniture?")
+ filling = models.TextField(_(u"Filling"), blank=True, null=True)
interpretation = models.TextField(_(u"Interpretation"), blank=True,
null=True)
- filling = models.TextField(_(u"Filling"), blank=True, null=True)
- datings = models.ManyToManyField(Dating)
- units = models.ManyToManyField(Unit)
taq = models.IntegerField(_(u"TAQ"), blank=True, null=True,
help_text=_("\"Terminus Ante Quem\" the context record can't have been "
"created after this date"))
@@ -566,8 +575,6 @@ class ContextRecord(BaseHistorizedItem, OwnPerms):
" created before this date"))
tpq_estimated = models.IntegerField(_(u"Estimated TPQ"), blank=True,
null=True, help_text=_("Estimation of a \"Terminus Post Quem\""))
- location = models.CharField(_(u"Location"), max_length=200,
- help_text=_(u"A short description of the location of the context record"))
history = HistoricalRecords()
class Meta:
diff --git a/ishtar/furnitures/urls.py b/ishtar/furnitures/urls.py
index c93f14c78..0e28043e2 100644
--- a/ishtar/furnitures/urls.py
+++ b/ishtar/furnitures/urls.py
@@ -63,6 +63,8 @@ urlpatterns = patterns('',
url(BASE_URL + r'operation_administrativeact_deletion/(?P<step>.+)$',
ishtar_forms.operation_administrativeact_deletion_wizard,
name='operation_administrativeact_deletion'),
+ url(BASE_URL + r'record_creation/(?P<step>.+)$',
+ ishtar_forms.record_creation_wizard, name='record_creation'),
)
for section in menu.childs:
for menu_item in section.childs:
diff --git a/static/media/style.css b/static/media/style.css
index 27a31c08b..5d00ff793 100644
--- a/static/media/style.css
+++ b/static/media/style.css
@@ -29,6 +29,10 @@ label:first-letter {
text-transform: uppercase;
}
+textarea{
+ height:80px;
+}
+
td{
text-align:left;
}