diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-20 15:25:07 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-10-20 15:25:07 +0200 | 
| commit | dc7abf75836b59ad33d92da04fe727320400d512 (patch) | |
| tree | b26e820671aa6af552a4b03147c44a9d2aa84be8 /archaeological_finds/forms.py | |
| parent | 029d08540f66524c371ae87ede5c1281fbe2c568 (diff) | |
| download | Ishtar-dc7abf75836b59ad33d92da04fe727320400d512.tar.bz2 Ishtar-dc7abf75836b59ad33d92da04fe727320400d512.zip | |
Djangoization - Major refactoring (step 3)
Reorganization of views, urls, menus, admin, forms.
Changes on models.
Diffstat (limited to 'archaeological_finds/forms.py')
| -rw-r--r-- | archaeological_finds/forms.py | 525 | 
1 files changed, 525 insertions, 0 deletions
| diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py new file mode 100644 index 000000000..7d64214f5 --- /dev/null +++ b/archaeological_finds/forms.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_finds = current_item.base_finds.all() +            if base_finds: +                return base_finds[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_finds__context_record'] = dct.pop('pk') +        return dct + +class ItemForm(forms.Form): +    form_label = _("Item") +    base_model = 'base_finds' +    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_finds__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_finds__context_record__parcel__town = get_town_field() +    base_finds__context_record__operation__year = forms.IntegerField( +                                                             label=_(u"Year")) +    base_finds__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_finds__item__description = forms.CharField(label=_(u"Description")) +    base_finds__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_finds__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',) +""" | 
