diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2011-07-01 20:56:07 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2011-07-01 20:56:07 +0200 | 
| commit | 48827b3dbcd37a0e0655c4d3e17d77d6112d9f40 (patch) | |
| tree | bf633d5f57baab695160ed4bb949c8ab77c27ce8 | |
| parent | 08b2fd834f068fa30bb6a32d595e9ae564a389bc (diff) | |
| download | Ishtar-48827b3dbcd37a0e0655c4d3e17d77d6112d9f40.tar.bz2 Ishtar-48827b3dbcd37a0e0655c4d3e17d77d6112d9f40.zip | |
Work on warehouse packaging (refs #500)
| -rw-r--r-- | ishtar/ishtar_base/forms.py | 15 | ||||
| -rw-r--r-- | ishtar/ishtar_base/forms_items.py | 91 | ||||
| -rw-r--r-- | ishtar/ishtar_base/models.py | 43 | ||||
| -rw-r--r-- | ishtar/ishtar_base/urls.py | 12 | ||||
| -rw-r--r-- | ishtar/ishtar_base/views.py | 24 | 
5 files changed, 159 insertions, 26 deletions
| diff --git a/ishtar/ishtar_base/forms.py b/ishtar/ishtar_base/forms.py index 29d9ab4d6..9faba2ac9 100644 --- a/ishtar/ishtar_base/forms.py +++ b/ishtar/ishtar_base/forms.py @@ -269,7 +269,18 @@ class Wizard(NamedUrlSessionFormWizard):                      value = form.cleaned_data[key]                      if key in associated_models:                          if value: -                            value = associated_models[key].objects.get(pk=value) +                            model = associated_models[key] +                            if isinstance(value, unicode) \ +                             or isinstance(value, str) and "," in value: +                                value = value.split(",") +                            if isinstance(value, list) \ +                             or isinstance(value, tuple): +                                value = [model.objects.get(pk=val) +                                         for val in value if val] +                                if len(value) == 1: +                                    value = value[0] +                            else: +                                value = model.objects.get(pk=value)                          else:                              value = None                      dct[key] = value @@ -335,7 +346,7 @@ class Wizard(NamedUrlSessionFormWizard):                  m = getattr(self.model, dependant_item)                  model = m.field.rel.to                  c_dct = other_objs[dependant_item].copy() -                if hasattr(model, 'history'): +                if issubclass(model, models.BaseHistorizedItem):                      c_dct['history_modifier'] = request.user                  c_item = model(**c_dct)                  c_item.save() diff --git a/ishtar/ishtar_base/forms_items.py b/ishtar/ishtar_base/forms_items.py index 484902341..a89dc7cf1 100644 --- a/ishtar/ishtar_base/forms_items.py +++ b/ishtar/ishtar_base/forms_items.py @@ -185,10 +185,7 @@ class BaseTreatmentForm(forms.Form):      associated_models = {'treatment_type':models.TreatmentType,                           'person':models.Person,                           'location':models.Warehouse} -    treatment_type = forms.ChoiceField(label=_(u"Treatment type"), -                               choices=models.TreatmentType.get_types()) -    description = forms.CharField(label=_(u"Description"), -                                  widget=forms.Textarea, required=False) +    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), @@ -198,11 +195,20 @@ class BaseTreatmentForm(forms.Form):       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} @@ -213,13 +219,42 @@ class ItemMultipleFormSelection(forms.Form):  class ContainerForm(forms.Form):      form_label = _(u"Container") -    associated_models = {'container_type':models.ContainerType,}      reference = forms.CharField(label=_(u"Reference")) -    container_type = forms.ChoiceField(label=_(u"Container type"), -                               choices=models.ContainerType.get_types()) +    container_type = forms.ChoiceField(label=_(u"Container type"), choices=[]) +    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)])      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 + +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] @@ -242,13 +277,13 @@ def check_treatment(form_name, type_key, type_list=[], not_type_list=[]):      return func  class ResultItemForm(forms.Form): -    form_label = _("Resulting item") +    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=_("Precise description"), +    description = forms.CharField(label=_(u"Precise description"),                                    widget=forms.Textarea) -    material_type = forms.ChoiceField(label=_("Material type"), +    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)")) @@ -292,6 +327,42 @@ treatment_creation_wizard = TreatmentWizard([  # Warehouse management #  ######################## +class PackagingWizard(TreatmentWizard): +    pass + +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"Person"), +         widget=widgets.JQueryAutoComplete( +           reverse_lazy('autocomplete-person'), associated_model=models.Person), +           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) + +    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([ +    ('base-packaging', BasePackagingForm), +    ('container-packaging', ContainerSelectForm), +    ('multiselecitems-packaging', ItemPackagingFormSelection), +    ('final-packaging', FinalForm)], +     url_name='warehouse_packaging',) +  """  warehouse_packaging_wizard = ItemSourceWizard([           ('selec-warehouse_packaging', ItemsSelection), diff --git a/ishtar/ishtar_base/models.py b/ishtar/ishtar_base/models.py index 37af19f87..ee22b9973 100644 --- a/ishtar/ishtar_base/models.py +++ b/ishtar/ishtar_base/models.py @@ -74,7 +74,8 @@ def valid_ids(cls):              try:                  cls.objects.get(pk=v)              except ObjectDoesNotExist: -                raise ValidationError(_(u"Not a valid item.")) +                raise ValidationError( +                                   _(u"An item selected is not a valid item."))      return func  # unique validator for models @@ -150,11 +151,11 @@ class GeneralType(models.Model):          return self.label      @classmethod -    def get_help(cls, dct={}): +    def get_help(cls, dct={}, exclude=[]):          help_text = cls.HELP_TEXT          c_rank = -1          help_items = u"\n" -        for item in cls.get_types(dct=dct, instances=True): +        for item in cls.get_types(dct=dct, instances=True, exclude=exclude):              if hasattr(item, '__iter__'):                  # TODO: manage multiple levels                  continue @@ -175,18 +176,21 @@ class GeneralType(models.Model):          return u""      @classmethod -    def get_types(cls, dct={}, instances=False): +    def get_types(cls, dct={}, instances=False, exclude=[]):          base_dct = dct.copy()          if hasattr(cls, 'parent'): -            return cls._get_parent_types(base_dct, instances) -        return cls._get_types(base_dct, instances) +            return cls._get_parent_types(base_dct, instances, exclude=exclude) +        return cls._get_types(base_dct, instances, exclude=exclude)      @classmethod -    def _get_types(cls, dct={}, instances=False): +    def _get_types(cls, dct={}, instances=False, exclude=[]):          dct['available'] = True          if not instances:              yield ('', '--') -        for item in cls.objects.filter(**dct).all(): +        items = cls.objects.filter(**dct) +        if exclude: +            items = items.exclude(txt_idx__in=exclude) +        for item in items.all():              if instances:                  item.rank = 0                  yield item @@ -196,10 +200,12 @@ class GeneralType(models.Model):      PREFIX = "› "      @classmethod -    def _get_childs(cls, item, dct, prefix=0, instances=False): +    def _get_childs(cls, item, dct, prefix=0, instances=False, exclude=[]):          prefix += 1          dct['parent'] = item          childs = cls.objects.filter(**dct) +        if exclude: +            childs = childs.exclude(txt_idx__in=exclude)          if hasattr(cls, 'order'):              childs = childs.order_by('order')          for child in childs.all(): @@ -209,16 +215,19 @@ class GeneralType(models.Model):              else:                  yield (child.pk, SafeUnicode(prefix*cls.PREFIX + \                                           unicode(_(unicode(child))) )) -            for sub_child in cls._get_childs(child, dct, prefix, instances): +            for sub_child in cls._get_childs(child, dct, prefix, instances, +                                             exclude=exclude):                  yield sub_child      @classmethod -    def _get_parent_types(cls, dct={}, instances=False): +    def _get_parent_types(cls, dct={}, instances=False, exclude=[]):          dct['available'] = True          if not instances:              yield ('', '--')          dct['parent'] = None          items = cls.objects.filter(**dct) +        if exclude: +            items = items.exclude(txt_idx__in=exclude)          if hasattr(cls, 'order'):              items = items.order_by('order')          for item in items.all(): @@ -227,7 +236,7 @@ class GeneralType(models.Model):                  yield item              else:                  yield (item.pk, unicode(item)) -            for child in cls._get_childs(item, dct, instances): +            for child in cls._get_childs(item, dct, instances, exclude=exclude):                  yield child  class HistoryError(Exception): @@ -335,6 +344,10 @@ class LightHistorizedItem(BaseHistorizedItem):      class Meta:          abstract = True +    def save(self, *args, **kwargs): +        super(LightHistorizedItem, self).save(*args, **kwargs) +        return True +  class Departement(models.Model):      label = models.CharField(_(u"Label"), max_length=30)      number = models.CharField(_(u"Number"), unique=True, max_length=3) @@ -1129,6 +1142,12 @@ class Container(LightHistorizedItem):          verbose_name = _(u"Container")          verbose_name_plural = _(u"Containers") +    def __unicode__(self): +        lbl = self.reference +        lbl += u" - %s" % unicode(self.container_type) +        lbl += u" (%s)" % unicode(self.location) +        return lbl +  if settings.COUNTRY == 'fr':      class Arrondissement(models.Model):          name = models.CharField(u"Nom", max_length=30) diff --git a/ishtar/ishtar_base/urls.py b/ishtar/ishtar_base/urls.py index a45211c8b..d313f1b76 100644 --- a/ishtar/ishtar_base/urls.py +++ b/ishtar/ishtar_base/urls.py @@ -108,8 +108,6 @@ urlpatterns = patterns('',             ishtar_forms.item_creation_wizard, name='item_creation'),         url(BASE_URL + r'item_modification/(?P<step>.+)$',             ishtar_forms.item_modification_wizard, name='item_modification'), -       url(BASE_URL + r'treatment_creation/(?P<step>.+)$', -           ishtar_forms.treatment_creation_wizard, name='treatment_creation'),         url(BASE_URL + r'item_source_creation/(?P<step>.+)$',             ishtar_forms.item_source_creation_wizard,             name='item_source_creation'), @@ -119,6 +117,11 @@ urlpatterns = patterns('',         url(BASE_URL + r'item_source_deletion/(?P<step>.+)$',             ishtar_forms.item_source_deletion_wizard,             name='item_source_deletion'), +       # Treatments +       url(BASE_URL + r'treatment_creation/(?P<step>.+)$', +           ishtar_forms.treatment_creation_wizard, name='treatment_creation'), +       url(BASE_URL + r'warehouse_packaging/(?P<step>.+)$', +           ishtar_forms.warehouse_packaging_wizard, name='warehouse_packaging'),           )  for section in menu.childs:      for menu_item in section.childs: @@ -192,4 +195,9 @@ urlpatterns += patterns('ishtar.ishtar_base.views',             name='get-item'),       url(BASE_URL + r'get-itemsource/(?P<type>.+)?$',             'get_itemsource', name='get-itemsource'), +     # Treatments +     url(BASE_URL + r'autocomplete-container/?$', +           'autocomplete_container', name='autocomplete-container'), +     url(BASE_URL + r'new-container/(?P<parent_name>.+)?/$', +           'new_container', name='new-container'),  ) diff --git a/ishtar/ishtar_base/views.py b/ishtar/ishtar_base/views.py index a48912eeb..d4d82ac9f 100644 --- a/ishtar/ishtar_base/views.py +++ b/ishtar/ishtar_base/views.py @@ -549,6 +549,29 @@ def autocomplete_author(request):                                            for author in authors])      return HttpResponse(data, mimetype='text/plain') +def autocomplete_container(request): +    if not request.user.has_perm('ishtar_base.view_warehouse', +                                     models.Warehouse)\ +       and not request.user.has_perm('ishtar_base.view_own_warehouse', +                                     models.Warehouse): +        return HttpResponse(mimetype='text/plain') +    if not request.GET.get('term'): +        return HttpResponse(mimetype='text/plain') +    q = request.GET.get('term') +    query = Q() +    for q in q.split(' '): +        extra = Q(container_type__label__icontains=q) | \ +                Q(container_type__reference__icontains=q) | \ +                Q(reference__icontains=q) | \ +                Q(location__name=q) | \ +                Q(location__town=q) +        query = query & extra +    limit = 15 +    containers = models.Container.objects.filter(query)[:limit] +    data = json.dumps([{'id':container.pk, 'value':unicode(container)} +                                          for container in containers]) +    return HttpResponse(data, mimetype='text/plain') +  def new_item(model):      def func(request, parent_name):          model_name = model._meta.object_name @@ -580,6 +603,7 @@ new_warehouse = new_item(models.Warehouse)  new_person = new_item(models.Person)  new_organization = new_item(models.Organization)  new_author = new_item(models.Author) +new_container = new_item(models.Container)  def action(request, action_slug, obj_id=None, *args, **kwargs):      """ | 
