summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@peacefrogs.net>2011-07-08 00:01:50 +0200
committerÉtienne Loks <etienne.loks@peacefrogs.net>2011-07-08 00:01:50 +0200
commit1633ca5aed5c56cc833600552add496d5d29ef8c (patch)
treec9f996ff0c6556cfcf2a43a9854784ad4b0d838d
parent4ca3fed66033054172407bb56cd4c6edb7df06fb (diff)
downloadIshtar-1633ca5aed5c56cc833600552add496d5d29ef8c.tar.bz2
Ishtar-1633ca5aed5c56cc833600552add496d5d29ef8c.zip
Better packaging management (closes #515)
-rw-r--r--ishtar/ishtar_base/forms.py12
-rw-r--r--ishtar/ishtar_base/forms_common.py7
-rw-r--r--ishtar/ishtar_base/forms_context_records.py4
-rw-r--r--ishtar/ishtar_base/forms_items.py57
-rw-r--r--ishtar/ishtar_base/models.py5
-rw-r--r--ishtar/ishtar_base/urls.py2
-rw-r--r--ishtar/ishtar_base/views.py9
-rw-r--r--ishtar/ishtar_base/widgets.py13
8 files changed, 77 insertions, 32 deletions
diff --git a/ishtar/ishtar_base/forms.py b/ishtar/ishtar_base/forms.py
index f69b5dcd4..9d106aed0 100644
--- a/ishtar/ishtar_base/forms.py
+++ b/ishtar/ishtar_base/forms.py
@@ -733,7 +733,8 @@ class ClosingWizard(Wizard):
context_instance=RequestContext(request))
def get_form_selection(class_name, label, key, model, base_form, get_url,
- not_selected_error=_(u"You should select an item.")):
+ not_selected_error=_(u"You should select an item."), new=False,
+ new_message=_(u"Add a new item")):
"""
Generate a class selection form
class_name -- name of the class
@@ -742,6 +743,8 @@ def get_form_selection(class_name, label, key, model, base_form, get_url,
base_form -- base form to select
get_url -- url to get the item
not_selected_error -- message displayed when no item is selected
+ new -- can add new items
+ new_message -- message of link to add new items
"""
attrs = {'_main_key':key,
'_not_selected_error':not_selected_error,
@@ -749,12 +752,15 @@ def get_form_selection(class_name, label, key, model, base_form, get_url,
'associated_models':{key:model},
'currents':{key:model},}
attrs[key] = forms.IntegerField(label="", required=False,
- widget=widgets.JQueryJqGrid(reverse_lazy(get_url),
- base_form(), model), validators=[models.valid_id(model)])
+ validators=[models.valid_id(model)],
+ widget=widgets.JQueryJqGrid(reverse_lazy(get_url), base_form(), model,
+ new=new, new_message=new_message))
def clean(self):
cleaned_data = self.cleaned_data
if self._main_key not in cleaned_data \
or not cleaned_data[self._main_key]:
raise forms.ValidationError(self._not_selected_error)
return cleaned_data
+ attrs['clean'] = clean
return type(class_name, (forms.Form,), attrs)
+
diff --git a/ishtar/ishtar_base/forms_common.py b/ishtar/ishtar_base/forms_common.py
index 616569d94..739f3953e 100644
--- a/ishtar/ishtar_base/forms_common.py
+++ b/ishtar/ishtar_base/forms_common.py
@@ -66,6 +66,13 @@ def get_person_field(label=_(u"Person"), required=True, person_type=None):
return forms.IntegerField(widget=widget, label=label, required=required,
validators=[models.valid_id(models.Person)])
+def get_warehouse_field(label=_(u"Warehouse"), required=True):
+ # !FIXME hard_link, reverse_lazy doen't seem to work with formsets
+ url = "/" + settings.URL_PATH + 'autocomplete-warehouse'
+ widget = widgets.JQueryAutoComplete(url, associated_model=models.Warehouse)
+ return forms.IntegerField(widget=widget, label=label, required=required,
+ validators=[models.valid_id(models.Warehouse)])
+
class WarehouseForm(forms.Form):
name = forms.CharField(label=_(u"Name"), max_length=40,
validators=[name_validator])
diff --git a/ishtar/ishtar_base/forms_context_records.py b/ishtar/ishtar_base/forms_context_records.py
index 27b7fc6f2..7024b523a 100644
--- a/ishtar/ishtar_base/forms_context_records.py
+++ b/ishtar/ishtar_base/forms_context_records.py
@@ -136,8 +136,8 @@ class RecordFormSelection(forms.Form):
def clean(self):
cleaned_data = self.cleaned_data
if 'pk' not in cleaned_data or not cleaned_data['pk']:
- raise forms.ValidationError(_(u"You should select a context "
- u"record."))
+ raise forms.ValidationError(_(u"You should at least select one "
+ u"context record."))
return cleaned_data
diff --git a/ishtar/ishtar_base/forms_items.py b/ishtar/ishtar_base/forms_items.py
index 44886cc32..54c733751 100644
--- a/ishtar/ishtar_base/forms_items.py
+++ b/ishtar/ishtar_base/forms_items.py
@@ -37,8 +37,8 @@ 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, SourceForm, SourceWizard, \
- SourceSelect, SourceDeletionForm, AuthorFormset
+from forms_common import get_town_field, get_warehouse_field, SourceForm, \
+ SourceWizard, SourceSelect, SourceDeletionForm, AuthorFormset
from forms_context_records import RecordFormSelection
class ItemWizard(Wizard):
@@ -220,11 +220,17 @@ class ItemMultipleFormSelection(forms.Form):
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"Location"),
+ location = forms.IntegerField(label=_(u"Warehouse"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-warehouse'), associated_model=models.Warehouse,
new=True),
@@ -249,15 +255,6 @@ class ContainerForm(forms.Form):
new_item.save()
return new_item
-class ContainerSelectForm(forms.Form):
- form_label = _(u"Container")
- associated_models = {'container':models.Container,}
- container = forms.IntegerField(label=_(u"Container"),
- widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-container'),
- associated_model=models.Container, new=True),
- validators=[models.valid_id(models.Container)])
-
-
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]
@@ -326,28 +323,49 @@ treatment_creation_wizard = TreatmentWizard([
},
url_name='treatment_creation',)
-########################
-# Warehouse management #
-########################
+#############
+# 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")
@@ -355,15 +373,10 @@ class BasePackagingForm(forms.Form):
'person':models.Person,
'location':models.Warehouse}
treatment_type = forms.IntegerField(label="", widget=forms.HiddenInput)
- person = forms.IntegerField(label=_(u"Person"),
+ 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)])
- 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)])
start_date = forms.DateField(label=_(u"Date"), required=False,
widget=widgets.JQueryDate)
@@ -376,8 +389,8 @@ class ItemPackagingFormSelection(ItemMultipleFormSelection):
form_label = _(u"Packaged items")
warehouse_packaging_wizard = PackagingWizard([
+ ('seleccontainer-packaging', ContainerFormSelection),
('base-packaging', BasePackagingForm),
- ('container-packaging', ContainerSelectForm),
('multiselecitems-packaging', ItemPackagingFormSelection),
('final-packaging', FinalForm)],
url_name='warehouse_packaging',)
diff --git a/ishtar/ishtar_base/models.py b/ishtar/ishtar_base/models.py
index 90e593131..0cf15f072 100644
--- a/ishtar/ishtar_base/models.py
+++ b/ishtar/ishtar_base/models.py
@@ -1009,6 +1009,8 @@ class Item(BaseHistorizedItem, OwnPerms):
downstream_treatment = models.ForeignKey("Treatment", blank=True, null=True,
related_name='upstream_treatment', verbose_name=_("Downstream treatment"))
dating = models.ForeignKey(Dating, verbose_name=_(u"Dating"))
+ container = models.ForeignKey('Container', verbose_name=_(u"Container"),
+ blank=True, null=True, related_name='items')
history = HistoricalRecords()
def duplicate(self, user):
@@ -1161,7 +1163,8 @@ class ContainerType(GeneralType):
verbose_name_plural = _(u"Container types")
class Container(LightHistorizedItem):
- location = models.ForeignKey(Warehouse, verbose_name=_(u"Location"))
+ TABLE_COLS = ['reference', 'container_type', 'location',]
+ location = models.ForeignKey(Warehouse, verbose_name=_(u"Warehouse"))
container_type = models.ForeignKey(ContainerType,
verbose_name=_("Container type"))
reference = models.CharField(_(u"Reference"), max_length=40)
diff --git a/ishtar/ishtar_base/urls.py b/ishtar/ishtar_base/urls.py
index d313f1b76..3c5351c57 100644
--- a/ishtar/ishtar_base/urls.py
+++ b/ishtar/ishtar_base/urls.py
@@ -195,6 +195,8 @@ urlpatterns += patterns('ishtar.ishtar_base.views',
name='get-item'),
url(BASE_URL + r'get-itemsource/(?P<type>.+)?$',
'get_itemsource', name='get-itemsource'),
+ url(BASE_URL + r'get-container/$', 'get_container',
+ name='get-container'),
# Treatments
url(BASE_URL + r'autocomplete-container/?$',
'autocomplete_container', name='autocomplete-container'),
diff --git a/ishtar/ishtar_base/views.py b/ishtar/ishtar_base/views.py
index d4d82ac9f..fcacc305a 100644
--- a/ishtar/ishtar_base/views.py
+++ b/ishtar/ishtar_base/views.py
@@ -508,6 +508,13 @@ get_itemsource = get_item(models.ItemSource,
'item__dating__period':'item__dating__period__pk',
'item__description':'item__description__icontains',
})
+get_container = get_item(models.Container,
+ 'get_container', 'container',
+ extra_request_keys={
+'location':'location__pk',
+'container_type':'container_type__pk',
+'reference':'reference__icontains',
+ })
def autocomplete_warehouse(request):
if not request.user.has_perm('ishtar_base.view_warehouse', models.Warehouse)\
@@ -588,7 +595,7 @@ def new_item(model):
dct['new_item_pk'] = new_item.pk
dct['parent_name'] = parent_name
dct['parent_pk'] = parent_name
- if '_select_' in dct['parent_pk']:
+ if dct['parent_pk'] and '_select_' in dct['parent_pk']:
parents = dct['parent_pk'].split('_')
dct['parent_pk'] = "_".join([parents[0]] + parents[2:])
return render_to_response('window.html', dct,
diff --git a/ishtar/ishtar_base/widgets.py b/ishtar/ishtar_base/widgets.py
index cb257325c..5d46cb625 100644
--- a/ishtar/ishtar_base/widgets.py
+++ b/ishtar/ishtar_base/widgets.py
@@ -205,7 +205,8 @@ class JQueryJqGrid(forms.RadioSelect):
]}
def __init__(self, source, form, associated_model, attrs={},
- table_cols='TABLE_COLS', multiple=False, multiple_cols=[2]):
+ table_cols='TABLE_COLS', multiple=False, multiple_cols=[2], new=False,
+ new_message=""):
self.source = source
self.form = form
self.attrs = attrs
@@ -213,6 +214,7 @@ class JQueryJqGrid(forms.RadioSelect):
self.table_cols = table_cols
self.multiple = multiple
self.multiple_cols = multiple_cols
+ self.new, self.new_message = new, new_message
def render(self, name, value=None, attrs=None):
t = loader.get_template('form_snippet.html')
@@ -220,8 +222,13 @@ class JQueryJqGrid(forms.RadioSelect):
rendered += """
</table>
<button id='search_%s' class='submit'>%s</button>
-<h4>%s</h4>
-""" % (name, unicode(_("Search")), unicode(_("Search and select an item")))
+""" % (name, unicode(_("Search")))
+ if self.new:
+ model_name = self.associated_model._meta.object_name.lower()
+ url_new = reverse('new-' + model_name)
+ rendered += u'<p><a href="#" onclick="open_window(\'%s\');">'\
+ u'%s</a></p>' % (url_new, unicode(self.new_message))
+ rendered += "\n<h4>%s</h4>\n" % unicode(_("Search and select an item"))
extra_cols = []
col_names, col_idx = [], []
for k in self.form.fields: