diff options
Diffstat (limited to 'archaeological_finds/wizards.py')
| -rw-r--r-- | archaeological_finds/wizards.py | 294 | 
1 files changed, 279 insertions, 15 deletions
diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index 0e0fe80e1..7f4e1b498 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -17,8 +17,9 @@  # See the file COPYING for details. +from django.contrib import messages  from django.core.exceptions import ObjectDoesNotExist, PermissionDenied -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, pgettext  from ishtar_common.forms import reverse_lazy  from ishtar_common.wizards import Wizard, DeletionWizard, SearchWizard @@ -55,11 +56,21 @@ class FindWizard(Wizard):              if base_finds:                  return base_finds[0].context_record +    def get_current_basefinds(self): +        find = self.get_current_object() +        if not find: +            return [] +        return find.base_finds.all() +      def get_form_kwargs(self, step=None):          kwargs = super(FindWizard, self).get_form_kwargs(step) -        if step not in ('find-find_creation', 'find-find_modification'): +        if step not in ( +                'find-find_creation', 'find-find_modification', +                'simplefind-find_modification',):              return kwargs          kwargs['context_record'] = self.get_current_contextrecord() +        if step == 'simplefind-find_modification': +            kwargs['base_finds'] = self.get_current_basefinds()          return kwargs      def get_context_data(self, form, **kwargs): @@ -75,8 +86,8 @@ class FindWizard(Wizard):              (_(u"Context record"), unicode(current_cr)))          return context -    def get_extra_model(self, dct, form_list): -        dct = super(FindWizard, self).get_extra_model(dct, form_list) +    def get_extra_model(self, dct, m2m, form_list): +        dct = super(FindWizard, self).get_extra_model(dct, m2m, form_list)          dct['order'] = 1          if 'pk' in dct and type(dct['pk']) == ContextRecord:              dct['base_finds__context_record'] = dct.pop('pk') @@ -90,6 +101,10 @@ class FindModificationWizard(FindWizard):          'selec-find_modification': ['pk'],          'selecw-find_modification': ['pk'],      } +    wizard_templates = { +        'simplefind-find_modification': +            'ishtar/wizard/wizard_simplefind.html', +    }  class FindDeletionWizard(DeletionWizard): @@ -106,11 +121,59 @@ class TreatmentSearch(SearchWizard):      model = models.Treatment -class TreatmentWizard(Wizard): +class TreatmentBase(Wizard):      model = models.Treatment      wizard_done_window = reverse_lazy('show-treatment') +    base_url = "" +    saved_args = {"treatment_type_list": []} + +    def get_current_finds(self): +        step = self.steps.current +        if not step: +            return +        find_form_key = 'selecfind-' + self.base_url +        find_ids = self.session_get_value(find_form_key, "resulting_pk") +        try: +            return [ +                models.Find.objects.get(pk=int(find_id.strip())) +                for find_id in find_ids.split(u',') +            ] +        except(TypeError, ValueError, AttributeError, ObjectDoesNotExist): +            pass + +    def get_form_initial(self, step, data=None): +        initial = super(TreatmentBase, self).get_form_initial(step) +        base_step = 'basetreatment-' + self.base_url +        if step != base_step: +            return initial +        finds = self.get_current_finds() +        if not finds: +            return initial +        locations = [find.container.location.pk for find in finds +                     if find.container] +        # no location or multiple locations +        if not locations or len(set(locations)) != 1: +            return initial +        if not initial: +            initial = {} +        initial['location'] = locations[0] +        return initial + +    def get_extra_model(self, dct, m2m, form_list): +        dct = super(TreatmentBase, self).get_extra_model(dct, m2m, form_list) +        dct['treatment_type_list'] = [] +        for k, v in m2m: +            if k == 'treatment_type': +                if type(v) not in (list, tuple): +                    v = [v] +                dct['treatment_type_list'] += v +        return dct + + +class TreatmentWizard(TreatmentBase):      basket_step = 'basetreatment-treatment_creation' -    saved_args = {"items": []} +    saved_args = {"items": [], "treatment_type_list": []} +    base_url = 'treatment_creation'      def get_form_kwargs(self, step, **kwargs):          kwargs = super(TreatmentWizard, self).get_form_kwargs(step, **kwargs) @@ -119,25 +182,31 @@ class TreatmentWizard(Wizard):          kwargs['user'] = self.request.user          return kwargs -    def get_extra_model(self, dct, form_list): +    def get_extra_model(self, dct, m2m, form_list):          """          Get items concerned by the treatment          """ -        dct = super(TreatmentWizard, self).get_extra_model(dct, form_list) +        dct = super(TreatmentWizard, self).get_extra_model(dct, m2m, form_list)          if 'resulting_pk' in dct: -            try: -                find = models.Find.objects.get(pk=dct.pop('resulting_pk')) -                if 'own' in self.current_right \ -                        and not find.is_own(dct['history_modifier']): +            dct['items'] = [] +            pks = dct.pop('resulting_pk').split(u',') +            for pk in pks: +                try: +                    find = models.Find.objects.get(pk=pk) +                    dct['items'].append(find) +                except models.Find.DoesNotExist:                      raise PermissionDenied -                dct['items'] = [find] -            except models.Find.DoesNotExist: -                raise PermissionDenied          if 'basket' in dct:              basket = dct.pop('basket')              if basket.user.pk != dct['history_modifier'].pk:                  raise PermissionDenied              dct['items'] = list(basket.items.all()) + +        if 'items' in dct: +            for find in dct['items']: +                if 'own' in self.current_right \ +                        and not find.is_own(dct['history_modifier']): +                    raise PermissionDenied          return dct @@ -145,7 +214,196 @@ class TreatmentModificationWizard(TreatmentWizard):      modification = True +class TreatmentN1Wizard(TreatmentBase): +    saved_args = {"upstream_items": [], "resulting_find": None, +                  "treatment_type_list": []} +    base_url = 'treatment_creation_n1' + +    def _update_simple_initial_from_finds(self, initial, find, k): +        r_k = "resulting_" + k +        if getattr(find, k) and r_k in initial: +            # pop k when value is inconsistent between finds +            if initial[r_k] and initial[r_k] != getattr(find, k).pk: +                initial.pop(r_k) +            else: +                initial[r_k] = getattr(find, k).pk +        return initial + +    def _update_multi_initial_from_finds(self, initial, find, k): +        r_k = "resulting_" + k +        for value in getattr(find, k + 's').all(): +            if value.pk not in initial[r_k]: +                initial[r_k].append(value.pk) +        return initial + +    def _update_num_initial_from_finds(self, initial, find, k): +        r_k = "resulting_" + k +        if not getattr(find, k): +            return initial +        if initial[r_k] is None: +            initial[r_k] = 0 +        initial[r_k] += getattr(find, k) +        return initial + +    def _update_char_initial_from_finds(self, initial, find, k, sep=' ; '): +        r_k = "resulting_" + k +        value = getattr(find, k) +        if not value: +            return initial +        value = value.strip() +        if not initial[r_k]: +            initial[r_k] = value +        else: +            # new value is entirely inside the current value +            if value == initial[r_k] or (value + sep) in initial[r_k] or \ +                    (sep + value) in initial[r_k]: +                return initial +            initial[r_k] += sep + value +        return initial + +    def get_form_initial(self, step, data=None): +        initial = super(TreatmentN1Wizard, self).get_form_initial(step) +        if step != 'resultingfind-treatment_creation_n1': +            return initial +        finds = self.get_current_finds() +        if not finds: +            return initial +        simple_key = ['material_type_quality'] +        multi_key = ['material_type', 'object_type', 'communicabilitie'] +        numeric_key = ['find_number', 'min_number_of_individuals'] +        desc_key = ['decoration', 'inscription', 'comment', 'dating_comment'] +        char_key = ['manufacturing_place'] + +        for k in simple_key + numeric_key + desc_key + char_key: +            initial["resulting_" + k] = None +        for k in multi_key: +            initial["resulting_" + k] = [] + +        for find in finds: +            for k in simple_key: +                initial = self._update_simple_initial_from_finds( +                    initial, find, k) +            for k in multi_key: +                initial = self._update_multi_initial_from_finds( +                    initial, find, k) +            for k in numeric_key: +                initial = self._update_num_initial_from_finds( +                    initial, find, k) +            for k in char_key: +                initial = self._update_char_initial_from_finds( +                    initial, find, k, sep=' ; ') +            for k in desc_key: +                initial = self._update_char_initial_from_finds( +                    initial, find, k, sep='\n') + +        for k in initial.keys(): +            if initial[k] is None: +                initial.pop(k) +        return initial + +    def get_extra_model(self, dct, m2m, form_list): +        """ +        Get items concerned by the treatment +        """ +        dct = super(TreatmentN1Wizard, self).get_extra_model( +            dct, m2m, form_list) +        if 'resulting_pk' not in dct: +            return dct + +        dct['upstream_items'] = [] +        # manage upstream items +        pks = dct.pop('resulting_pk') +        if hasattr(pks, 'split'): +            pks = pks.split(u',')  # unicode or string +        for pk in pks: +            try: +                find = models.Find.objects.get(pk=pk) +                dct['upstream_items'].append(find) +            except models.Find.DoesNotExist: +                raise PermissionDenied + +        for find in dct['upstream_items']: +            if 'own' in self.current_right \ +                    and not find.is_own(dct['history_modifier']): +                raise PermissionDenied + +        # extract data of the new find +        dct['resulting_find'] = {} +        for k in dct.keys(): +            if k.startswith('resulting_') and k != "resulting_find": +                dct['resulting_find'][ +                    k[len('resulting_'):] +                ] = dct.pop(k) +        return dct + + +class Treatment1NWizard(TreatmentBase): +    saved_args = {"upstream_item": None, "resulting_finds": None, +                  "treatment_type_list": []} +    base_url = 'treatment_creation_1n' + +    def get_form_kwargs(self, step, **kwargs): +        kwargs = super(Treatment1NWizard, self).get_form_kwargs(step, **kwargs) +        if step != 'resultingfind-treatment_creation_1n': +            return kwargs +        kwargs['user'] = self.request.user +        return kwargs + +    def get_form_initial(self, step, data=None): +        initial = super(Treatment1NWizard, self).get_form_initial(step) +        if step != 'resultingfinds-treatment_creation_1n': +            return initial +        finds = self.get_current_finds() +        if not finds: +            return initial +        lbl = finds[0].label +        initial['resultings_basket_name'] = unicode(_(u"Basket")) + u" - " + lbl +        initial['resultings_label'] = lbl + u"-" +        return initial + +    def get_extra_model(self, dct, m2m, form_list): +        """ +        Get items concerned by the treatment +        """ +        dct = super(Treatment1NWizard, self).get_extra_model( +            dct, m2m, form_list) +        if 'resulting_pk' not in dct: +            return dct + +        # manage upstream item +        pk = dct.pop('resulting_pk') +        try: +            find = models.Find.objects.get(pk=pk) +            dct['upstream_item'] = find +        except models.Find.DoesNotExist: +            raise PermissionDenied + +        if 'own' in self.current_right \ +                and not find.is_own(dct['history_modifier']): +            raise PermissionDenied + +        # extract attributes to generate the new find +        dct['resulting_finds'] = {} +        for k in dct.keys(): +            if k.startswith('resultings_'): +                dct['resulting_finds'][ +                    k[len('resultings_'):] +                ] = dct.pop(k) +        messages.add_message( +            self.request, messages.INFO, +            unicode(_(u"The new basket: \"{}\" have been created with the " +                      u"resulting items. This search have been pinned.") +                    ).format(dct["resulting_finds"]["basket_name"]) +        ) +        self.request.session["pin-search-find"] = u'{}="{}"'.format( +            unicode(pgettext("key for text search", u"basket")), +            dct["resulting_finds"]["basket_name"]) +        self.request.session['find'] = '' +        return dct + +  class TreatmentDeletionWizard(DeletionWizard): +    wizard_confirm = 'ishtar/wizard/wizard_treatement_deletion.html'      model = models.Treatment      fields = ['label', 'other_reference', 'year', 'index',                'treatment_types', 'location', 'person', 'organization', @@ -243,3 +501,9 @@ class FindBasketWizard(Wizard):  class FindBasketEditWizard(FindBasketWizard):      edit = True +    alt_is_own_method = 'get_write_query_owns' + + +class FindBasketDeletionWizard(DeletionWizard): +    wizard_confirm = 'ishtar/wizard/wizard_findbasket_deletion.html' +    model = models.FindBasket  | 
