diff options
| 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 | 
| commit | 3349d76a08dd164a412ca8846e9a17ab05df82d6 (patch) | |
| tree | c9f996ff0c6556cfcf2a43a9854784ad4b0d838d | |
| parent | 2fc9a3feb4548e47a04c90f4ef76654d78a8396a (diff) | |
| download | Ishtar-3349d76a08dd164a412ca8846e9a17ab05df82d6.tar.bz2 Ishtar-3349d76a08dd164a412ca8846e9a17ab05df82d6.zip | |
Better packaging management (closes #515)
| -rw-r--r-- | ishtar/ishtar_base/forms.py | 12 | ||||
| -rw-r--r-- | ishtar/ishtar_base/forms_common.py | 7 | ||||
| -rw-r--r-- | ishtar/ishtar_base/forms_context_records.py | 4 | ||||
| -rw-r--r-- | ishtar/ishtar_base/forms_items.py | 57 | ||||
| -rw-r--r-- | ishtar/ishtar_base/models.py | 5 | ||||
| -rw-r--r-- | ishtar/ishtar_base/urls.py | 2 | ||||
| -rw-r--r-- | ishtar/ishtar_base/views.py | 9 | ||||
| -rw-r--r-- | ishtar/ishtar_base/widgets.py | 13 | 
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:
 | 
