summaryrefslogtreecommitdiff
path: root/ishtar_common/forms_items.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/forms_items.py')
-rw-r--r--ishtar_common/forms_items.py525
1 files changed, 525 insertions, 0 deletions
diff --git a/ishtar_common/forms_items.py b/ishtar_common/forms_items.py
new file mode 100644
index 000000000..b763d94b2
--- /dev/null
+++ b/ishtar_common/forms_items.py
@@ -0,0 +1,525 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2011 É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.
+
+"""
+Items forms definitions
+"""
+import datetime
+
+from django import forms
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.core import validators
+from django.core.exceptions import ObjectDoesNotExist
+from django.utils.safestring import mark_safe
+from django.db.models import Max
+from django.utils.translation import ugettext_lazy as _
+
+from ishtar import settings
+
+import models
+import widgets
+from forms import Wizard, FinalForm, FormSet, SearchWizard, DeletionWizard,\
+ FloatField, formset_factory, get_now, get_form_selection, reverse_lazy
+from forms_common import get_town_field, get_warehouse_field, SourceForm, \
+ SourceWizard, SourceSelect, SourceDeletionForm, AuthorFormset
+from forms_context_records import RecordFormSelection
+
+class ItemWizard(Wizard):
+ model = models.Item
+
+ def get_current_contextrecord(self, request, storage):
+ step = storage.get_current_step()
+ if not step:
+ return
+ if step.endswith('_creation'): # a context record has been selected
+ main_form_key = 'selecrecord-' + self.url_name
+ try:
+ idx = int(self.session_get_value(request, storage,
+ main_form_key, 'pk'))
+ current_cr = models.ContextRecord.objects.get(pk=idx)
+ return current_cr
+ except(TypeError, ValueError, ObjectDoesNotExist):
+ pass
+ current_item = self.get_current_object(request, storage)
+ if current_item:
+ base_items = current_item.base_items.all()
+ if base_items:
+ return base_items[0].context_record
+
+ def get_template_context(self, request, storage, form=None):
+ """
+ Get the operation and context record "reminder" on top of wizard forms
+ """
+ context = super(ItemWizard, self).get_template_context(request,
+ storage, form)
+ current_cr = self.get_current_contextrecord(request, storage)
+ if not current_cr:
+ return context
+ operation = current_cr.operation
+ items = []
+ if hasattr(operation, 'code_patriarche') and operation.code_patriarche:
+ items.append(unicode(operation.code_patriarche))
+ items.append("-".join((unicode(operation.year),
+ unicode(operation.operation_code))))
+ reminder = unicode(_("Current operation: ")) + u" - ".join(items)
+ reminder += u"<br/>" + unicode(_("Current context record: "))\
+ + unicode(current_cr.label)
+ context['reminder'] = mark_safe(reminder)
+ return context
+
+ def get_extra_model(self, dct, request, storage, form_list):
+ dct = super(ItemWizard, self).get_extra_model(dct, request, storage,
+ form_list)
+ dct['order'] = 1
+ if 'pk' in dct and type(dct['pk']) == models.ContextRecord:
+ dct['base_items__context_record'] = dct.pop('pk')
+ return dct
+
+class ItemForm(forms.Form):
+ form_label = _("Item")
+ base_model = 'base_items'
+ associated_models = {'material_type':models.MaterialType,}
+ label = forms.CharField(label=_(u"ID"),
+ validators=[validators.MaxLengthValidator(60)])
+ description = forms.CharField(label=_("Description"),
+ widget=forms.Textarea)
+ base_items__is_isolated = forms.NullBooleanField(label=_(u"Is isolated?"),
+ required=False)
+ material_type = forms.ChoiceField(label=_("Material type"),
+ choices=models.MaterialType.get_types())
+ volume = FloatField(label=_(u"Volume (l)"), required=False)
+ weight = FloatField(label=_(u"Weight (g)"), required=False)
+ item_number = forms.IntegerField(label=_(u"Item number"), required=False)
+
+class DateForm(forms.Form):
+ form_label = _("Dating")
+ base_model = 'dating'
+ associated_models = {'dating__dating_type':models.DatingType,
+ 'dating__quality':models.DatingQuality,
+ 'dating__period':models.Period}
+ dating__period = forms.ChoiceField(label=_("Period"),
+ choices=models.Period.get_types())
+ dating__start_date = forms.IntegerField(label=_(u"Start date"),
+ required=False)
+ dating__end_date = forms.IntegerField(label=_(u"End date"), required=False)
+ dating__quality = forms.ChoiceField(label=_("Quality"), required=False,
+ choices=models.DatingQuality.get_types())
+ dating__dating_type = forms.ChoiceField(label=_("Dating type"),
+ required=False, choices=[])
+
+ def __init__(self, *args, **kwargs):
+ super(DateForm, self).__init__(*args, **kwargs)
+ self.fields['dating__dating_type'].choices = models.DatingType.get_types()
+ self.fields['dating__dating_type'].help_text = models.DatingType.get_help()
+
+item_creation_wizard = ItemWizard([
+ ('selecrecord-item_creation', RecordFormSelection),
+ ('item-item_creation', ItemForm),
+ ('dating-item_creation', DateForm),
+ ('final-item_creation', FinalForm)],
+ url_name='item_creation',)
+
+class ItemSelect(forms.Form):
+ base_items__context_record__parcel__town = get_town_field()
+ base_items__context_record__operation__year = forms.IntegerField(
+ label=_(u"Year"))
+ base_items__context_record__operation__code_patriarche = \
+ forms.IntegerField(label=_(u"Code PATRIARCHE"))
+ dating__period = forms.ChoiceField(label=_(u"Period"), choices=[])
+ # TODO search by warehouse
+ material_type = forms.ChoiceField(label=_(u"Material type"), choices=[])
+ base_items__item__description = forms.CharField(label=_(u"Description"))
+ base_items__is_isolated = forms.NullBooleanField(label=_(u"Is isolated?"))
+
+ def __init__(self, *args, **kwargs):
+ super(ItemSelect, self).__init__(*args, **kwargs)
+ self.fields['dating__period'].choices = \
+ models.Period.get_types()
+ self.fields['dating__period'].help_text = \
+ models.Period.get_help()
+ self.fields['material_type'].choices = \
+ models.MaterialType.get_types()
+ self.fields['material_type'].help_text = \
+ models.MaterialType.get_help()
+
+class ItemFormSelection(forms.Form):
+ form_label = _("Item search")
+ associated_models = {'pk':models.Item}
+ currents = {'pk':models.Item}
+ pk = forms.IntegerField(label="", required=False,
+ widget=widgets.JQueryJqGrid(reverse_lazy('get-item'),
+ ItemSelect(), models.Item, source_full=reverse_lazy('get-item-full')),
+ validators=[models.valid_id(models.Item)])
+
+item_search_wizard = SearchWizard([
+ ('general-item_search', ItemFormSelection)],
+ url_name='item_search',)
+
+class ItemModificationWizard(ItemWizard):
+ modification = True
+
+item_modification_wizard = ItemModificationWizard([
+ ('selec-item_modification', ItemFormSelection),
+ ('item-item_modification', ItemForm),
+ ('dating-item_modification', DateForm),
+ ('final-item_modification', FinalForm)],
+ url_name='item_modification',)
+
+class TreatmentWizard(Wizard):
+ model = models.Treatment
+
+class BaseTreatmentForm(forms.Form):
+ form_label = _(u"Base treatment")
+ associated_models = {'treatment_type':models.TreatmentType,
+ 'person':models.Person,
+ 'location':models.Warehouse}
+ treatment_type = forms.ChoiceField(label=_(u"Treatment type"), choices=[])
+ person = forms.IntegerField(label=_(u"Person"),
+ widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person'),
+ associated_model=models.Person, new=True),
+ validators=[models.valid_id(models.Person)])
+ location = forms.IntegerField(label=_(u"Location"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-warehouse'), associated_model=models.Warehouse,
+ new=True),
+ validators=[models.valid_id(models.Warehouse)])
+ description = forms.CharField(label=_(u"Description"),
+ widget=forms.Textarea, required=False)
+ start_date = forms.DateField(label=_(u"Start date"), required=False,
+ widget=widgets.JQueryDate)
+ end_date = forms.DateField(label=_(u"End date"), required=False,
+ widget=widgets.JQueryDate)
+
+ def __init__(self, *args, **kwargs):
+ super(BaseTreatmentForm, self).__init__(*args, **kwargs)
+ self.fields['treatment_type'].choices = models.TreatmentType.get_types(
+ exclude=['packaging'])
+ self.fields['treatment_type'].help_text = models.TreatmentType.get_help(
+ exclude=['packaging'])
+
+class ItemMultipleFormSelection(forms.Form):
+ form_label = _(u"Upstream items")
+ associated_models = {'items':models.Item}
+ associated_labels = {'items':_(u"Items")}
+ items = forms.CharField(label="", required=False,
+ widget=widgets.JQueryJqGrid(reverse_lazy('get-item'),
+ ItemSelect(), models.Item, multiple=True, multiple_cols=[2, 3, 4]),
+ validators=[models.valid_ids(models.Item)])
+
+ def clean(self):
+ if not 'items' in self.cleaned_data or not self.cleaned_data['items']:
+ raise forms.ValidationError(_(u"You should at least select one "
+ u"archaeological item."))
+ return self.cleaned_data
+
+class ContainerForm(forms.Form):
+ form_label = _(u"Container")
+ reference = forms.CharField(label=_(u"Reference"))
+ container_type = forms.ChoiceField(label=_(u"Container type"), choices=[])
+ location = forms.IntegerField(label=_(u"Warehouse"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-warehouse'), associated_model=models.Warehouse,
+ new=True),
+ validators=[models.valid_id(models.Warehouse)])
+ comment = forms.CharField(label=_(u"Comment"),
+ widget=forms.Textarea, required=False)
+
+ def __init__(self, *args, **kwargs):
+ super(ContainerForm, self).__init__(*args, **kwargs)
+ self.fields['container_type'].choices = \
+ models.ContainerType.get_types()
+ self.fields['container_type'].help_text = \
+ models.ContainerType.get_help()
+
+ def save(self, user):
+ dct = self.cleaned_data
+ dct['history_modifier'] = user
+ dct['container_type'] = models.ContainerType.objects.get(
+ pk=dct['container_type'])
+ dct['location'] = models.Warehouse.objects.get(pk=dct['location'])
+ new_item = models.Container(**dct)
+ new_item.save()
+ return new_item
+
+def check_treatment(form_name, type_key, type_list=[], not_type_list=[]):
+ type_list = [models.TreatmentType.objects.get(txt_idx=tpe).pk
+ for tpe in type_list]
+ not_type_list = [models.TreatmentType.objects.get(txt_idx=tpe).pk
+ for tpe in not_type_list]
+ def func(self, request, storage):
+ if storage.prefix not in request.session or \
+ 'step_data' not in request.session[storage.prefix] or \
+ form_name not in request.session[storage.prefix]['step_data'] or\
+ form_name + '-' + type_key not in \
+ request.session[storage.prefix]['step_data'][form_name]:
+ return False
+ try:
+ type = int(request.session[storage.prefix]['step_data']\
+ [form_name][form_name+'-'+type_key])
+ return (not type_list or type in type_list) \
+ and type not in not_type_list
+ except ValueError:
+ return False
+ return func
+
+class ResultItemForm(forms.Form):
+ form_label = _(u"Resulting item")
+ associated_models = {'material_type':models.MaterialType}
+ label = forms.CharField(label=_(u"ID"),
+ validators=[validators.MaxLengthValidator(60)])
+ description = forms.CharField(label=_(u"Precise description"),
+ widget=forms.Textarea)
+ material_type = forms.ChoiceField(label=_(u"Material type"),
+ choices=models.MaterialType.get_types())
+ volume = forms.IntegerField(label=_(u"Volume (l)"))
+ weight = forms.IntegerField(label=_(u"Weight (g)"))
+ item_number = forms.IntegerField(label=_(u"Item number"))
+
+ResultItemFormSet = formset_factory(ResultItemForm, can_delete=True,
+ formset=FormSet)
+ResultItemFormSet.form_label = _(u"Resulting items")
+
+class UpstreamItemFormSelection(ItemFormSelection):
+ form_label = _(u"Upstream item")
+
+treatment_creation_wizard = TreatmentWizard([
+ ('basetreatment-treatment_creation', BaseTreatmentForm),
+ ('selecitem-treatment_creation', UpstreamItemFormSelection),
+ ('multiselecitems-treatment_creation', ItemMultipleFormSelection),
+ ('container-treatment_creation', ContainerForm),
+ ('resultitem-treatment_creation', ResultItemForm),
+ ('resultitems-treatment_creation', ResultItemFormSet),
+ ('final-treatment_creation', FinalForm)],
+ condition_list={
+'selecitem-treatment_creation':
+ check_treatment('basetreatment-treatment_creation', 'treatment_type',
+ not_type_list=['physical_grouping', 'packaging']),
+'multiselecitems-treatment_creation':
+ check_treatment('basetreatment-treatment_creation', 'treatment_type',
+ ['physical_grouping', 'packaging']),
+'resultitems-treatment_creation':
+ check_treatment('basetreatment-treatment_creation', 'treatment_type',
+ ['split']),
+'resultitem-treatment_creation':
+ check_treatment('basetreatment-treatment_creation', 'treatment_type',
+ not_type_list=['split']),
+'container-treatment_creation':
+ check_treatment('basetreatment-treatment_creation', 'treatment_type',
+ ['packaging']),
+ },
+ url_name='treatment_creation',)
+
+#############
+# Packaging #
+#############
+
+class PackagingWizard(TreatmentWizard):
+ def save_model(self, dct, m2m, whole_associated_models, request, storage,
+ form_list, return_object):
+ dct = self.get_extra_model(dct, request, storage, form_list)
+ obj = self.get_current_saved_object(request, storage)
+ dct['location'] = dct['container'].location
+ items = dct.pop('items')
+ treatment = models.Treatment(**dct)
+ treatment.save()
+ if not hasattr(items, '__iter__'):
+ items = [items]
+ for item in items:
+ new = item.duplicate(request.user)
+ item.downstream_treatment = treatment
+ item.save()
+ new.upstream_treatment = treatment
+ new.container = dct['container']
+ new.save()
+ res = render_to_response('wizard_done.html', {},
+ context_instance=RequestContext(request))
+ return return_object and (obj, res) or res
+
+class ContainerSelect(forms.Form):
+ location = get_warehouse_field()
+ container_type = forms.ChoiceField(label=_(u"Container type"), choices=[])
+ reference = forms.CharField(label=_(u"Reference"))
+
+ def __init__(self, *args, **kwargs):
+ super(ContainerSelect, self).__init__(*args, **kwargs)
+ self.fields['container_type'].choices = \
+ models.ContainerType.get_types()
+ self.fields['container_type'].help_text = \
+ models.ContainerType.get_help()
+
+ContainerFormSelection = get_form_selection(
+ 'ContainerFormSelection', _(u"Container search"), 'container',
+ models.Container, ContainerSelect, 'get-container',
+ _(u"You should select a container."), new=True,
+ new_message=_(u"Add a new container"))
+
+class BasePackagingForm(forms.Form):
+ form_label = _(u"Packaging")
+ associated_models = {'treatment_type':models.TreatmentType,
+ 'person':models.Person,
+ 'location':models.Warehouse}
+ treatment_type = forms.IntegerField(label="", widget=forms.HiddenInput)
+ person = forms.IntegerField(label=_(u"Packager"),
+ widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person'),
+ associated_model=models.Person, new=True),
+ validators=[models.valid_id(models.Person)])
+ start_date = forms.DateField(label=_(u"Date"), required=False,
+ widget=widgets.JQueryDate)
+
+ def __init__(self, *args, **kwargs):
+ super(BasePackagingForm, self).__init__(*args, **kwargs)
+ self.fields['treatment_type'].initial = \
+ models.TreatmentType.objects.get(txt_idx='packaging').pk
+
+class ItemPackagingFormSelection(ItemMultipleFormSelection):
+ form_label = _(u"Packaged items")
+
+warehouse_packaging_wizard = PackagingWizard([
+ ('seleccontainer-packaging', ContainerFormSelection),
+ ('base-packaging', BasePackagingForm),
+ ('multiselecitems-packaging', ItemPackagingFormSelection),
+ ('final-packaging', FinalForm)],
+ url_name='warehouse_packaging',)
+
+"""
+warehouse_packaging_wizard = ItemSourceWizard([
+ ('selec-warehouse_packaging', ItemsSelection),
+ ('final-warehouse_packaging', FinalForm)],
+ url_name='warehouse_packaging',)
+"""
+#############################################
+# Source management for archaelogical items #
+#############################################
+
+class ItemSourceWizard(SourceWizard):
+ model = models.ItemSource
+
+SourceItemFormSelection = get_form_selection(
+ 'SourceItemFormSelection', _(u"Archaelogical item search"), 'item',
+ models.Item, ItemSelect, 'get-item',
+ _(u"You should select an archaelogical item."))
+
+item_source_creation_wizard = ItemSourceWizard([
+ ('selec-item_source_creation', SourceItemFormSelection),
+ ('source-item_source_creation', SourceForm),
+ ('authors-item_source_creation', AuthorFormset),
+ ('final-item_source_creation', FinalForm)],
+ url_name='item_source_creation',)
+
+class ItemSourceSelect(SourceSelect):
+ item__base_items__context_record__operation__year = forms.IntegerField(
+ label=_(u"Year of the operation"))
+ item__dating__period = forms.ChoiceField(
+ label=_(u"Period of the archaelogical item"),
+ choices=[])
+ item__material_type = forms.ChoiceField(
+ label=_("Material type of the archaelogical item"),
+ choices=models.MaterialType.get_types())
+ item__description = forms.CharField(
+ label=_(u"Description of the archaelogical item"))
+
+ def __init__(self, *args, **kwargs):
+ super(ItemSourceSelect, self).__init__(*args, **kwargs)
+ self.fields['item__dating__period'].choices = \
+ models.Period.get_types()
+ self.fields['item__dating__period'].help_text = \
+ models.Period.get_help()
+ self.fields['item__material_type'].choices = \
+ models.MaterialType.get_types()
+ self.fields['item__material_type'].help_text = \
+ models.MaterialType.get_help()
+
+ItemSourceFormSelection = get_form_selection(
+ 'ItemSourceFormSelection', _(u"Documentation search"), 'pk',
+ models.ItemSource, ItemSourceSelect, 'get-itemsource',
+ _(u"You should select a document."))
+
+item_source_modification_wizard = ItemSourceWizard([
+ ('selec-item_source_modification', ItemSourceFormSelection),
+ ('source-item_source_modification', SourceForm),
+ ('authors-item_source_modification', AuthorFormset),
+ ('final-item_source_modification', FinalForm)],
+ url_name='item_source_modification',)
+
+class ItemSourceDeletionWizard(DeletionWizard):
+ model = models.ItemSource
+ fields = ['item', 'title', 'source_type', 'authors',]
+
+item_source_deletion_wizard = ItemSourceDeletionWizard([
+ ('selec-item_source_deletion', ItemSourceFormSelection),
+ ('final-item_source_deletion', SourceDeletionForm)],
+ url_name='item_source_deletion',)
+
+"""
+
+####################################
+# Source management for treatments #
+####################################
+
+class TreatmentSourceWizard(SourceWizard):
+ model = models.TreamentSource
+
+SourceTreatementFormSelection = get_form_selection(
+ 'SourceTreatmentFormSelection', _(u"Treatment search"), 'operation',
+ models.Treatment, TreatmentSelect, 'get-treatment',
+ _(u"You should select a treatment."))
+
+treatment_source_creation_wizard = TreatmentSourceWizard([
+ ('selec-treatment_source_creation', SourceTreatmentFormSelection),
+ ('source-treatment_source_creation', SourceForm),
+ ('authors-treatment_source_creation', AuthorFormset),
+ ('final-treatment_source_creation', FinalForm)],
+ url_name='treatment_source_creation',)
+
+class TreatmentSourceSelect(SourceSelect):
+ operation__towns = get_town_field(label=_(u"Operation's town"))
+ treatment__treatment_type = forms.ChoiceField(label=_(u"Operation type"),
+ choices=[])
+ operation__year = forms.IntegerField(label=_(u"Operation's year"))
+
+ def __init__(self, *args, **kwargs):
+ super(OperationSourceSelect, self).__init__(*args, **kwargs)
+ self.fields['operation__operation_type'].choices = \
+ models.OperationType.get_types()
+ self.fields['operation__operation_type'].help_text = \
+ models.OperationType.get_help()
+
+
+OperationSourceFormSelection = get_form_selection(
+ 'OperationSourceFormSelection', _(u"Documentation search"), 'pk',
+ models.OperationSource, OperationSourceSelect, 'get-operationsource',
+ _(u"You should select a document."))
+
+operation_source_modification_wizard = OperationSourceWizard([
+ ('selec-operation_source_modification', OperationSourceFormSelection),
+ ('source-operation_source_modification', SourceForm),
+ ('authors-operation_source_modification', AuthorFormset),
+ ('final-operation_source_modification', FinalForm)],
+ url_name='operation_source_modification',)
+
+class OperationSourceDeletionWizard(DeletionWizard):
+ model = models.OperationSource
+ fields = ['operation', 'title', 'source_type', 'authors',]
+
+operation_source_deletion_wizard = OperationSourceDeletionWizard([
+ ('selec-operation_source_deletion', OperationSourceFormSelection),
+ ('final-operation_source_deletion', SourceDeletionForm)],
+ url_name='operation_source_deletion',)
+"""