diff options
-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): """ |