summaryrefslogtreecommitdiff
path: root/archaeological_finds
diff options
context:
space:
mode:
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
commitdc7abf75836b59ad33d92da04fe727320400d512 (patch)
treeb26e820671aa6af552a4b03147c44a9d2aa84be8 /archaeological_finds
parent029d08540f66524c371ae87ede5c1281fbe2c568 (diff)
downloadIshtar-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')
-rw-r--r--archaeological_finds/admin.py75
-rw-r--r--archaeological_finds/forms.py525
-rw-r--r--archaeological_finds/ishtar_menu.py67
-rw-r--r--archaeological_finds/migrations/0001_initial.py188
-rw-r--r--archaeological_finds/models.py134
-rw-r--r--archaeological_finds/urls.py52
-rw-r--r--archaeological_finds/views.py43
7 files changed, 923 insertions, 161 deletions
diff --git a/archaeological_finds/admin.py b/archaeological_finds/admin.py
new file mode 100644
index 000000000..096f05bf3
--- /dev/null
+++ b/archaeological_finds/admin.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2012 É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.conf import settings
+from django.contrib import admin
+
+from ishtar_common.admin import HistorizedObjectAdmin
+
+import models
+
+class BaseFindAdmin(HistorizedObjectAdmin):
+ list_display = ('label', 'context_record', 'is_isolated')
+ search_fields = ('label', 'context_record__parcel__operation__name',)
+ model = models.BaseFind
+
+admin.site.register(models.BaseFind, BaseFindAdmin)
+
+class FindAdmin(HistorizedObjectAdmin):
+ list_display = ('label', 'material_type', 'dating', 'volume', 'weight',
+ 'find_number',)
+ list_filter = ('material_type',)
+ search_fields = ('label', "dating__period__label")
+ model = models.Find
+
+admin.site.register(models.Find, FindAdmin)
+
+class FindSourceAdmin(admin.ModelAdmin):
+ list_display = ('find', 'title', 'source_type',)
+ list_filter = ('source_type',)
+ search_fields = ('title', )
+ model = models.FindSource
+
+admin.site.register(models.FindSource, FindSourceAdmin)
+
+class PropertyAdmin(admin.ModelAdmin):
+ list_display = ['find', 'person', 'start_date', 'end_date']
+ search_fields = ('find__label', 'person__name')
+ model = models.Property
+
+admin.site.register(models.Property, PropertyAdmin)
+
+class TreatmentAdmin(HistorizedObjectAdmin):
+ list_display = ('location', 'treatment_type', 'container', 'person')
+ list_filter = ('treatment_type',)
+ model = models.Treatment
+
+admin.site.register(models.Treatment, TreatmentAdmin)
+
+class TreatmentSourceAdmin(admin.ModelAdmin):
+ list_display = ('treatment', 'title', 'source_type',)
+ list_filter = ('source_type',)
+ search_fields = ('title',)
+ model = models.TreatmentSource
+
+admin.site.register(models.TreatmentSource, TreatmentSourceAdmin)
+
+basic_models = [models.MaterialType, models.TreatmentType]
+for model in basic_models:
+ admin.site.register(model)
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',)
+"""
diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py
new file mode 100644
index 000000000..55a498184
--- /dev/null
+++ b/archaeological_finds/ishtar_menu.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2012 É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.utils.translation import ugettext_lazy as _
+
+from ishtar_common.menu_base import SectionItem, MenuItem
+
+import models
+
+MENU_SECTIONS = [
+ (50, SectionItem('find_management', _(u"Find"),
+ childs=[
+ MenuItem('find_search', _(u"Search"),
+ model=models.Find,
+ access_controls=['view_item',
+ 'view_own_item']),
+ MenuItem('find_creation', _(u"Creation"),
+ model=models.Find,
+ access_controls=['add_item',
+ 'add_own_item']),
+ MenuItem('find_modification', _(u"Modification"),
+ model=models.Find,
+ access_controls=['change_item',
+ 'change_own_item']),
+ MenuItem('warehouse_packaging', _(u"Packaging"),
+ model=models.Treatment,
+ access_controls=['add_treatment', 'add_own_treatment']),
+ #MenuItem('treatment_creation', _(u"Add a treatment"),
+ # model=models.Treatment,
+ # access_controls=['add_treatment',
+ # 'add_own_treatment']),
+ SectionItem('find_source', _(u"Documentation"),
+ childs=[
+ MenuItem('find_source_creation',
+ _(u"Creation"),
+ model=models.FindSource,
+ access_controls=['change_item',
+ 'change_own_item']),
+ MenuItem('find_source_modification',
+ _(u"Modification"),
+ model=models.FindSource,
+ access_controls=['change_item',
+ 'change_own_item']),
+ MenuItem('find_source_deletion',
+ _(u"Deletion"),
+ model=models.FindSource,
+ access_controls=['change_item',
+ 'change_own_item']),
+ ])
+ ]))
+]
diff --git a/archaeological_finds/migrations/0001_initial.py b/archaeological_finds/migrations/0001_initial.py
index 03a45ed8d..eab75b03c 100644
--- a/archaeological_finds/migrations/0001_initial.py
+++ b/archaeological_finds/migrations/0001_initial.py
@@ -20,8 +20,8 @@ class Migration(SchemaMigration):
))
db.send_create_signal('archaeological_finds', ['MaterialType'])
- # Adding model 'HistoricalBaseItem'
- db.create_table('archaeological_finds_historicalbaseitem', (
+ # Adding model 'HistoricalBaseFind'
+ db.create_table('archaeological_finds_historicalbasefind', (
('id', self.gf('django.db.models.fields.IntegerField')(db_index=True, blank=True)),
('history_modifier_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
('label', self.gf('django.db.models.fields.CharField')(max_length=60)),
@@ -35,23 +35,23 @@ class Migration(SchemaMigration):
('history_user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)),
('history_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
))
- db.send_create_signal('archaeological_finds', ['HistoricalBaseItem'])
+ db.send_create_signal('archaeological_finds', ['HistoricalBaseFind'])
- # Adding model 'BaseItem'
- db.create_table('archaeological_finds_baseitem', (
+ # Adding model 'BaseFind'
+ db.create_table('archaeological_finds_basefind', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('history_modifier', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['auth.User'])),
('label', self.gf('django.db.models.fields.CharField')(max_length=60)),
('description', self.gf('django.db.models.fields.TextField')()),
- ('context_record', self.gf('django.db.models.fields.related.ForeignKey')(related_name='base_items', to=orm['archaeological_context_records.ContextRecord'])),
+ ('context_record', self.gf('django.db.models.fields.related.ForeignKey')(related_name='base_finds', to=orm['archaeological_context_records.ContextRecord'])),
('is_isolated', self.gf('django.db.models.fields.NullBooleanField')(null=True, blank=True)),
('index', self.gf('django.db.models.fields.IntegerField')(default=0)),
('material_index', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
- db.send_create_signal('archaeological_finds', ['BaseItem'])
+ db.send_create_signal('archaeological_finds', ['BaseFind'])
- # Adding model 'HistoricalItem'
- db.create_table('archaeological_finds_historicalitem', (
+ # Adding model 'HistoricalFind'
+ db.create_table('archaeological_finds_historicalfind', (
('id', self.gf('django.db.models.fields.IntegerField')(db_index=True, blank=True)),
('history_modifier_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
('order', self.gf('django.db.models.fields.IntegerField')()),
@@ -60,7 +60,7 @@ class Migration(SchemaMigration):
('material_type_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
('volume', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)),
('weight', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)),
- ('item_number', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('find_number', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('upstream_treatment_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
('downstream_treatment_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
('dating_id', self.gf('django.db.models.fields.IntegerField')(db_index=True, null=True, blank=True)),
@@ -70,10 +70,10 @@ class Migration(SchemaMigration):
('history_user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)),
('history_type', self.gf('django.db.models.fields.CharField')(max_length=1)),
))
- db.send_create_signal('archaeological_finds', ['HistoricalItem'])
+ db.send_create_signal('archaeological_finds', ['HistoricalFind'])
- # Adding model 'Item'
- db.create_table('archaeological_finds_item', (
+ # Adding model 'Find'
+ db.create_table('archaeological_finds_find', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('history_modifier', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['auth.User'])),
('order', self.gf('django.db.models.fields.IntegerField')()),
@@ -82,41 +82,41 @@ class Migration(SchemaMigration):
('material_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_finds.MaterialType'])),
('volume', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)),
('weight', self.gf('django.db.models.fields.FloatField')(null=True, blank=True)),
- ('item_number', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
+ ('find_number', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
('upstream_treatment', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='downstream_treatment', null=True, to=orm['archaeological_finds.Treatment'])),
('downstream_treatment', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='upstream_treatment', null=True, to=orm['archaeological_finds.Treatment'])),
('dating', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_context_records.Dating'])),
- ('container', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='items', null=True, to=orm['archaeological_warehouse.Container'])),
+ ('container', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='finds', null=True, to=orm['archaeological_warehouse.Container'])),
))
- db.send_create_signal('archaeological_finds', ['Item'])
+ db.send_create_signal('archaeological_finds', ['Find'])
- # Adding M2M table for field base_items on 'Item'
- db.create_table('archaeological_finds_item_base_items', (
+ # Adding M2M table for field base_finds on 'Find'
+ db.create_table('archaeological_finds_find_base_finds', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
- ('item', models.ForeignKey(orm['archaeological_finds.item'], null=False)),
- ('baseitem', models.ForeignKey(orm['archaeological_finds.baseitem'], null=False))
+ ('find', models.ForeignKey(orm['archaeological_finds.find'], null=False)),
+ ('basefind', models.ForeignKey(orm['archaeological_finds.basefind'], null=False))
))
- db.create_unique('archaeological_finds_item_base_items', ['item_id', 'baseitem_id'])
+ db.create_unique('archaeological_finds_find_base_finds', ['find_id', 'basefind_id'])
- # Adding model 'ItemSource'
- db.create_table('archaeological_finds_itemsource', (
+ # Adding model 'FindSource'
+ db.create_table('archaeological_finds_findsource', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
('source_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.SourceType'])),
('associated_url', self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True)),
('receipt_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
('creation_date', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
- ('item', self.gf('django.db.models.fields.related.ForeignKey')(related_name='source', to=orm['archaeological_finds.Item'])),
+ ('find', self.gf('django.db.models.fields.related.ForeignKey')(related_name='source', to=orm['archaeological_finds.Find'])),
))
- db.send_create_signal('archaeological_finds', ['ItemSource'])
+ db.send_create_signal('archaeological_finds', ['FindSource'])
- # Adding M2M table for field authors on 'ItemSource'
- db.create_table('archaeological_finds_itemsource_authors', (
+ # Adding M2M table for field authors on 'FindSource'
+ db.create_table('archaeological_finds_findsource_authors', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
- ('itemsource', models.ForeignKey(orm['archaeological_finds.itemsource'], null=False)),
+ ('findsource', models.ForeignKey(orm['archaeological_finds.findsource'], null=False)),
('author', models.ForeignKey(orm['ishtar_common.author'], null=False))
))
- db.create_unique('archaeological_finds_itemsource_authors', ['itemsource_id', 'author_id'])
+ db.create_unique('archaeological_finds_findsource_authors', ['findsource_id', 'author_id'])
# Adding model 'TreatmentType'
db.create_table('archaeological_finds_treatmenttype', (
@@ -186,7 +186,7 @@ class Migration(SchemaMigration):
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('history_modifier', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['auth.User'])),
('history_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
- ('item', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_finds.Item'])),
+ ('find', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_finds.Find'])),
('administrative_act', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_operations.AdministrativeAct'])),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.Person'])),
('start_date', self.gf('django.db.models.fields.DateField')()),
@@ -199,26 +199,26 @@ class Migration(SchemaMigration):
# Deleting model 'MaterialType'
db.delete_table('archaeological_finds_materialtype')
- # Deleting model 'HistoricalBaseItem'
- db.delete_table('archaeological_finds_historicalbaseitem')
+ # Deleting model 'HistoricalBaseFind'
+ db.delete_table('archaeological_finds_historicalbasefind')
- # Deleting model 'BaseItem'
- db.delete_table('archaeological_finds_baseitem')
+ # Deleting model 'BaseFind'
+ db.delete_table('archaeological_finds_basefind')
- # Deleting model 'HistoricalItem'
- db.delete_table('archaeological_finds_historicalitem')
+ # Deleting model 'HistoricalFind'
+ db.delete_table('archaeological_finds_historicalfind')
- # Deleting model 'Item'
- db.delete_table('archaeological_finds_item')
+ # Deleting model 'Find'
+ db.delete_table('archaeological_finds_find')
- # Removing M2M table for field base_items on 'Item'
- db.delete_table('archaeological_finds_item_base_items')
+ # Removing M2M table for field base_finds on 'Find'
+ db.delete_table('archaeological_finds_find_base_finds')
- # Deleting model 'ItemSource'
- db.delete_table('archaeological_finds_itemsource')
+ # Deleting model 'FindSource'
+ db.delete_table('archaeological_finds_findsource')
- # Removing M2M table for field authors on 'ItemSource'
- db.delete_table('archaeological_finds_itemsource_authors')
+ # Removing M2M table for field authors on 'FindSource'
+ db.delete_table('archaeological_finds_findsource_authors')
# Deleting model 'TreatmentType'
db.delete_table('archaeological_finds_treatmenttype')
@@ -265,7 +265,7 @@ class Migration(SchemaMigration):
'length': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'operation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'context_record'", 'to': "orm['archaeological_operations.Operation']"}),
- 'parcel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'context_record'", 'to': "orm['archaeological_context_records.Parcel']"}),
+ 'parcel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'context_record'", 'to': "orm['archaeological_operations.Parcel']"}),
'taq': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'taq_estimated': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'thickness': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
@@ -308,18 +308,6 @@ class Migration(SchemaMigration):
'order': ('django.db.models.fields.IntegerField', [], {}),
'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
- 'archaeological_context_records.parcel': {
- 'Meta': {'object_name': 'Parcel'},
- 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'parcels'", 'null': 'True', 'to': "orm['archaeological_files.File']"}),
- 'history_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'operation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'parcels'", 'null': 'True', 'to': "orm['archaeological_operations.Operation']"}),
- 'parcel_number': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
- 'section': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
- 'town': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parcels'", 'to': "orm['ishtar_common.Town']"}),
- 'year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
- },
'archaeological_context_records.unit': {
'Meta': {'object_name': 'Unit'},
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
@@ -382,9 +370,9 @@ class Migration(SchemaMigration):
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
- 'archaeological_finds.baseitem': {
- 'Meta': {'object_name': 'BaseItem'},
- 'context_record': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'base_items'", 'to': "orm['archaeological_context_records.ContextRecord']"}),
+ 'archaeological_finds.basefind': {
+ 'Meta': {'object_name': 'BaseFind'},
+ 'context_record': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'base_finds'", 'to': "orm['archaeological_context_records.ContextRecord']"}),
'description': ('django.db.models.fields.TextField', [], {}),
'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
@@ -393,8 +381,36 @@ class Migration(SchemaMigration):
'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
'material_index': ('django.db.models.fields.IntegerField', [], {'default': '0'})
},
- 'archaeological_finds.historicalbaseitem': {
- 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalBaseItem'},
+ 'archaeological_finds.find': {
+ 'Meta': {'object_name': 'Find'},
+ 'base_finds': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'find'", 'symmetrical': 'False', 'to': "orm['archaeological_finds.BaseFind']"}),
+ 'container': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'finds'", 'null': 'True', 'to': "orm['archaeological_warehouse.Container']"}),
+ 'dating': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_context_records.Dating']"}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'downstream_treatment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'upstream_treatment'", 'null': 'True', 'to': "orm['archaeological_finds.Treatment']"}),
+ 'find_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
+ 'material_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_finds.MaterialType']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'upstream_treatment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'downstream_treatment'", 'null': 'True', 'to': "orm['archaeological_finds.Treatment']"}),
+ 'volume': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+ 'weight': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'archaeological_finds.findsource': {
+ 'Meta': {'object_name': 'FindSource'},
+ 'associated_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.Author']", 'symmetrical': 'False'}),
+ 'creation_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'find': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source'", 'to': "orm['archaeological_finds.Find']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'receipt_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'source_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.SourceType']"}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+ },
+ 'archaeological_finds.historicalbasefind': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalBaseFind'},
'context_record_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {}),
'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
@@ -408,19 +424,19 @@ class Migration(SchemaMigration):
'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
'material_index': ('django.db.models.fields.IntegerField', [], {'default': '0'})
},
- 'archaeological_finds.historicalitem': {
- 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalItem'},
+ 'archaeological_finds.historicalfind': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalFind'},
'container_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'dating_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'downstream_treatment_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'find_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
- 'item_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
'material_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {}),
@@ -444,34 +460,6 @@ class Migration(SchemaMigration):
'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'treatment_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
},
- 'archaeological_finds.item': {
- 'Meta': {'object_name': 'Item'},
- 'base_items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'item'", 'symmetrical': 'False', 'to': "orm['archaeological_finds.BaseItem']"}),
- 'container': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'items'", 'null': 'True', 'to': "orm['archaeological_warehouse.Container']"}),
- 'dating': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_context_records.Dating']"}),
- 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
- 'downstream_treatment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'upstream_treatment'", 'null': 'True', 'to': "orm['archaeological_finds.Treatment']"}),
- 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'item_number': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'label': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
- 'material_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_finds.MaterialType']"}),
- 'order': ('django.db.models.fields.IntegerField', [], {}),
- 'upstream_treatment': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'downstream_treatment'", 'null': 'True', 'to': "orm['archaeological_finds.Treatment']"}),
- 'volume': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
- 'weight': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'})
- },
- 'archaeological_finds.itemsource': {
- 'Meta': {'object_name': 'ItemSource'},
- 'associated_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
- 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.Author']", 'symmetrical': 'False'}),
- 'creation_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source'", 'to': "orm['archaeological_finds.Item']"}),
- 'receipt_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
- 'source_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.SourceType']"}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
- },
'archaeological_finds.materialtype': {
'Meta': {'object_name': 'MaterialType'},
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
@@ -486,10 +474,10 @@ class Migration(SchemaMigration):
'Meta': {'object_name': 'Property'},
'administrative_act': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_operations.AdministrativeAct']"}),
'end_date': ('django.db.models.fields.DateField', [], {}),
+ 'find': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_finds.Find']"}),
'history_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_finds.Item']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Person']"}),
'start_date': ('django.db.models.fields.DateField', [], {})
},
@@ -588,6 +576,18 @@ class Migration(SchemaMigration):
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
+ 'archaeological_operations.parcel': {
+ 'Meta': {'object_name': 'Parcel'},
+ 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'parcels'", 'null': 'True', 'to': "orm['archaeological_files.File']"}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'operation': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'parcels'", 'null': 'True', 'to': "orm['archaeological_operations.Operation']"}),
+ 'parcel_number': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
+ 'section': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'town': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'parcels'", 'to': "orm['ishtar_common.Town']"}),
+ 'year': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
'archaeological_operations.period': {
'Meta': {'object_name': 'Period'},
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py
index cea9a35f1..c61e22e68 100644
--- a/archaeological_finds/models.py
+++ b/archaeological_finds/models.py
@@ -39,11 +39,11 @@ class MaterialType(GeneralType):
verbose_name = _(u"Material type")
verbose_name_plural = _(u"Material types")
-class BaseItem(BaseHistorizedItem, OwnPerms):
+class BaseFind(BaseHistorizedItem, OwnPerms):
label = models.CharField(_(u"ID"), max_length=60)
description = models.TextField(_(u"Description"))
context_record = models.ForeignKey(ContextRecord,
- related_name='base_items', verbose_name=_(u"Context Record"))
+ related_name='base_finds', verbose_name=_(u"Context Record"))
is_isolated = models.NullBooleanField(_(u"Is isolated?"), blank=True,
null=True)
index = models.IntegerField(u"Index", default=0)
@@ -51,40 +51,40 @@ class BaseItem(BaseHistorizedItem, OwnPerms):
history = HistoricalRecords()
class Meta:
- verbose_name = _(u"Base item")
- verbose_name_plural = _(u"Base items")
+ verbose_name = _(u"Base find")
+ verbose_name_plural = _(u"Base finds")
permissions = (
- ("view_own_baseitem", ugettext(u"Can view own Base item")),
- ("add_own_baseitem", ugettext(u"Can add own Base item")),
- ("change_own_baseitem", ugettext(u"Can change own Base item")),
- ("delete_own_baseitem", ugettext(u"Can delete own Base item")),
+ ("view_own_basefind", ugettext(u"Can view own Base find")),
+ ("add_own_basefind", ugettext(u"Can add own Base find")),
+ ("change_own_basefind", ugettext(u"Can change own Base find")),
+ ("delete_own_basefind", ugettext(u"Can delete own Base find")),
)
def __unicode__(self):
return self.label
- def get_last_item(self):
- #TODO: manage virtuals - property(last_item) ?
- items = self.item.filter().order_by("-order").all()
- return items and items[0]
+ def get_last_find(self):
+ #TODO: manage virtuals - property(last_find) ?
+ finds = self.find.filter().order_by("-order").all()
+ return finds and finds[0]
def full_label(self):
return self._real_label() or self._temp_label()
def material_type_label(self):
- item = self.get_last_item()
- items = [item and unicode(item.material_type) or '']
+ find = self.get_last_find()
+ finds = [find and unicode(find.material_type) or '']
ope = self.context_record.operation
- items += [ope.code_patriarche or \
+ finds += [ope.code_patriarche or \
(unicode(ope.year) + "-" + unicode(ope.operation_code))]
- items += [self.context_record.label, unicode(self.material_index)]
- return JOINT.join(items)
+ finds += [self.context_record.label, unicode(self.material_index)]
+ return JOINT.join(finds)
def _real_label(self):
if not self.context_record.parcel.operation.code_patriarche:
return
- item = self.get_last_item()
- lbl = item.label or self.label
+ find = self.get_last_find()
+ lbl = find.label or self.label
return JOINT.join([unicode(it) for it in (
self.context_record.parcel.operation.code_patriarche,
self.context_record.label,
@@ -93,25 +93,25 @@ class BaseItem(BaseHistorizedItem, OwnPerms):
def _temp_label(self):
if self.context_record.parcel.operation.code_patriarche:
return
- item = self.get_last_item()
- lbl = item.label or self.label
+ find = self.get_last_find()
+ lbl = find.label or self.label
return JOINT.join([unicode(it) for it in (
self.context_record.parcel.year,
self.index,
self.context_record.label,
lbl) if it])
-class Item(BaseHistorizedItem, OwnPerms):
+class Find(BaseHistorizedItem, OwnPerms):
TABLE_COLS = ['label', 'material_type', 'dating.period',
- 'base_items.context_record.parcel.town',
- 'base_items.context_record.parcel.operation.year',
- 'base_items.context_record.parcel.operation.operation_code',
- 'base_items.is_isolated']
+ 'base_finds.context_record.parcel.town',
+ 'base_finds.context_record.parcel.operation.year',
+ 'base_finds.context_record.parcel.operation.operation_code',
+ 'base_finds.is_isolated']
if settings.COUNTRY == 'fr':
TABLE_COLS.insert(6,
- 'base_items.context_record.parcel.operation.code_patriarche')
- base_items = models.ManyToManyField(BaseItem, verbose_name=_(u"Base item"),
- related_name='item')
+ 'base_finds.context_record.parcel.operation.code_patriarche')
+ base_finds = models.ManyToManyField(BaseFind, verbose_name=_(u"Base find"),
+ related_name='find')
order = models.IntegerField(_(u"Order"))
label = models.CharField(_(u"ID"), max_length=60)
description = models.TextField(_(u"Description"), blank=True, null=True)
@@ -119,7 +119,7 @@ class Item(BaseHistorizedItem, OwnPerms):
verbose_name = _(u"Material type"))
volume = models.FloatField(_(u"Volume (l)"), blank=True, null=True)
weight = models.FloatField(_(u"Weight (g)"), blank=True, null=True)
- item_number = models.IntegerField(_("Item number"), blank=True, null=True)
+ find_number = models.IntegerField(_("Find number"), blank=True, null=True)
upstream_treatment = models.ForeignKey("Treatment", blank=True, null=True,
related_name='downstream_treatment', verbose_name=_("Upstream treatment"))
downstream_treatment = models.ForeignKey("Treatment", blank=True, null=True,
@@ -127,15 +127,15 @@ class Item(BaseHistorizedItem, OwnPerms):
dating = models.ForeignKey(Dating, verbose_name=_(u"Dating"))
if WAREHOUSE_AVAILABLE:
container = models.ForeignKey(Container, verbose_name=_(u"Container"),
- blank=True, null=True, related_name='items')
+ blank=True, null=True, related_name='finds')
history = HistoricalRecords()
@classmethod
def get_years(cls):
years = set()
- items = cls.objects.filter(downstream_treatment__isnull=True)
- for item in items:
- bi = item.base_items.all()
+ finds = cls.objects.filter(downstream_treatment__isnull=True)
+ for find in finds:
+ bi = find.base_finds.all()
if not bi:
continue
bi = bi[0]
@@ -146,14 +146,14 @@ class Item(BaseHistorizedItem, OwnPerms):
@classmethod
def get_by_year(cls, year):
return cls.objects.filter(downstream_treatment__isnull=True,
- base_items__context_record__operation__start_date__year=year)
+ base_finds__context_record__operation__start_date__year=year)
@classmethod
def get_operations(cls):
operations = set()
- items = cls.objects.filter(downstream_treatment__isnull=True)
- for item in items:
- bi = item.base_items.all()
+ finds = cls.objects.filter(downstream_treatment__isnull=True)
+ for find in finds:
+ bi = find.base_finds.all()
if not bi:
continue
bi = bi[0]
@@ -164,7 +164,7 @@ class Item(BaseHistorizedItem, OwnPerms):
@classmethod
def get_by_operation(cls, operation_id):
return cls.objects.filter(downstream_treatment__isnull=True,
- base_items__context_record__operation__pk=operation_id)
+ base_finds__context_record__operation__pk=operation_id)
@classmethod
def get_total_number(cls):
@@ -173,23 +173,23 @@ class Item(BaseHistorizedItem, OwnPerms):
def duplicate(self, user):
dct = dict([(attr, getattr(self, attr)) for attr in ('order', 'label',
'description', 'material_type', 'volume', 'weight',
- 'item_number', 'dating')])
+ 'find_number', 'dating')])
dct['order'] += 1
dct['history_modifier'] = user
new = self.__class__(**dct)
new.save()
- for base_item in self.base_items.all():
- new.base_items.add(base_item)
+ for base_find in self.base_finds.all():
+ new.base_finds.add(base_find)
return new
class Meta:
- verbose_name = _(u"Item")
- verbose_name_plural = _(u"Items")
+ verbose_name = _(u"Find")
+ verbose_name_plural = _(u"Finds")
permissions = (
- ("view_own_item", ugettext(u"Can view own Item")),
- ("add_own_item", ugettext(u"Can add own Item")),
- ("change_own_item", ugettext(u"Can change own Item")),
- ("delete_own_item", ugettext(u"Can delete own Item")),
+ ("view_own_find", ugettext(u"Can view own Find")),
+ ("add_own_find", ugettext(u"Can add own Find")),
+ ("change_own_find", ugettext(u"Can change own Find")),
+ ("delete_own_find", ugettext(u"Can delete own Find")),
)
def __unicode__(self):
@@ -197,27 +197,27 @@ class Item(BaseHistorizedItem, OwnPerms):
def save(self, *args, **kwargs):
if not self.pk:
- super(Item, self).save(*args, **kwargs)
- for base_item in self.base_items.all():
- if not base_item.index:
- idx = BaseItem.objects.filter(context_record=\
- base_item.context_record).aggregate(Max('index'))
- base_item.index = idx and idx['index__max'] + 1 or 1
- if not base_item.material_index:
- idx = BaseItem.objects.filter(context_record=\
- base_item.context_record,
- item__material_type=self.material_type).aggregate(
+ super(Find, self).save(*args, **kwargs)
+ for base_find in self.base_finds.all():
+ if not base_find.index:
+ idx = BaseFind.objects.filter(context_record=\
+ base_find.context_record).aggregate(Max('index'))
+ base_find.index = idx and idx['index__max'] + 1 or 1
+ if not base_find.material_index:
+ idx = BaseFind.objects.filter(context_record=\
+ base_find.context_record,
+ find__material_type=self.material_type).aggregate(
Max('material_index'))
- base_item.material_index = idx and \
+ base_find.material_index = idx and \
idx['material_index__max'] + 1 or 1
- base_item.save()
- super(Item, self).save(*args, **kwargs)
+ base_find.save()
+ super(Find, self).save(*args, **kwargs)
-class ItemSource(Source):
+class FindSource(Source):
class Meta:
- verbose_name = _(u"Item documentation")
- verbose_name_plural = _(u"Item documentations")
- item = models.ForeignKey(Item, verbose_name=_(u"Item"),
+ verbose_name = _(u"Find documentation")
+ verbose_name_plural = _(u"Find documentations")
+ find = models.ForeignKey(Find, verbose_name=_(u"Find"),
related_name="source")
class TreatmentType(GeneralType):
@@ -265,7 +265,7 @@ class TreatmentSource(Source):
related_name="source")
class Property(LightHistorizedItem):
- item = models.ForeignKey(Item, verbose_name=_(u"Item"))
+ find = models.ForeignKey(Find, verbose_name=_(u"Find"))
administrative_act = models.ForeignKey(AdministrativeAct,
verbose_name=_(u"Administrative act"))
person = models.ForeignKey(Person, verbose_name=_(u"Person"))
@@ -277,5 +277,5 @@ class Property(LightHistorizedItem):
verbose_name_plural = _(u"Properties")
def __unicode__(self):
- return self.person + JOINT + self.item
+ return self.person + JOINT + self.find
diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py
new file mode 100644
index 000000000..4c733436d
--- /dev/null
+++ b/archaeological_finds/urls.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2012 É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.conf.urls.defaults import *
+
+"""
+import forms
+
+# forms
+urlpatterns = patterns('',
+ url(r'item_search/(?P<step>.+)$',
+ forms.item_search_wizard, name='item_search'),
+ url(r'item_creation/(?P<step>.+)$',
+ forms.item_creation_wizard, name='item_creation'),
+ url(r'item_modification/(?P<step>.+)$',
+ forms.item_modification_wizard, name='item_modification'),
+ url(r'item_source_creation/(?P<step>.+)$',
+ forms.item_source_creation_wizard,
+ name='item_source_creation'),
+ url(r'item_source_modification/(?P<step>.+)$',
+ forms.item_source_modification_wizard,
+ name='item_source_modification'),
+ url(r'item_source_deletion/(?P<step>.+)$',
+ forms.item_source_deletion_wizard,
+ name='item_source_deletion'),
+)
+
+urlpatterns += patterns('archaeological_finds.views',
+ url(r'get-find/(?P<type>.+)?$', 'get_find',
+ name='get-find'),
+ url(r'get-find-full/(?P<type>.+)?$', 'get_find',
+ name='get-find-full', kwargs={'full':True}),
+ url(r'get-findsource/(?P<type>.+)?$',
+ 'get_findsource', name='get-findsource'),
+)
+"""
diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py
new file mode 100644
index 000000000..af428d59e
--- /dev/null
+++ b/archaeological_finds/views.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2010-2012 É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 ishtar_common.views import get_item, show_item, revert_item
+import models
+
+get_find = get_item(models.Find,
+ 'get_find', 'find',
+ bool_fields = ['base_finds__is_isolated'],
+ base_request={'downstream_treatment__isnull':True},
+ extra_request_keys={
+'base_finds__context_record__parcel__town':
+ 'base_finds__context_record__parcel__town',
+'base_finds__context_record__operation__year':
+ 'base_finds__context_record__operation__year__contains',
+'base_finds__context_record__operation__code_patriarche':
+ 'base_finds__context_record__operation__code_patriarche',
+'dating__period':'dating__period__pk',
+'base_finds__find__description':'base_finds__find__description__icontains',
+'base_finds__is_isolated':'base_finds__is_isolated'})
+get_findsource = get_item(models.FindSource,
+ 'get_findsource', 'findsource',
+ extra_request_keys={
+'find__context_record__operation__year':'find__context_record__operation__year',
+'find__dating__period':'find__dating__period__pk',
+'find__description':'find__description__icontains',
+ })