diff options
| -rw-r--r-- | archaeological_finds/forms.py | 4 | ||||
| -rw-r--r-- | ishtar_common/forms.py | 2 | ||||
| -rw-r--r-- | ishtar_common/forms_common.py | 22 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/wizard/confirm_wizard.html | 3 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/wizard/delete_wizard.html | 42 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html | 4 | ||||
| -rw-r--r-- | ishtar_common/views.py | 2 | ||||
| -rw-r--r-- | ishtar_common/wizards.py | 109 | 
8 files changed, 177 insertions, 11 deletions
| diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index a333033c6..a08821d85 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -54,7 +54,7 @@ from ishtar_common import widgets  from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \      FloatField, reverse_lazy, TableSelect, get_now, FinalForm, \      ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect, \ -    PkWizardSearch +    MultiSearchForm  from ishtar_common.forms_common import get_town_field  from ishtar_common.models import valid_id, valid_ids, get_current_profile, \      SpatialReferenceSystem, Area, OperationType, IshtarUser @@ -1452,7 +1452,7 @@ class FindDeletionForm(FinalForm):      confirm_end_msg = _(u"Would you like to delete this find?") -class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection): +class UpstreamFindFormSelection(MultiSearchForm, FindFormSelection):      form_label = _(u"Upstream finds")      current_model = models.Find      pk_key = 'resulting_pk' diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 8acd5ffcc..ae7c6ca14 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -372,7 +372,7 @@ class CustomForm(BSForm):          return sorted(customs, key=lambda x: x[1]) -class PkWizardSearch(object): +class MultiSearchForm(object):      current_model = None      pk_key = None diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 235138eea..42bf90691 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -44,7 +44,8 @@ from ishtar_common.templatetags.link_to_window import simple_link_to_window  from .forms import FinalForm, FormSet, reverse_lazy, name_validator, \      TableSelect, ManageOldType, CustomForm, FieldType, FormHeader, \      FormSetWithDeleteSwitches, BSForm, get_data_from_formset, \ -    file_size_validator, HistorySelect, CustomFormSearch, QAForm, IshtarForm +    file_size_validator, HistorySelect, CustomFormSearch, QAForm, IshtarForm, \ +    MultiSearchForm  from ishtar_common.utils import is_downloadable, clean_session_cache, \      max_size_help @@ -515,6 +516,25 @@ class PersonFormSelection(CustomFormSearch):          validators=[models.valid_id(models.Person)]) +class PersonFormMultiSelection(MultiSearchForm, PersonFormSelection): +    pk_key = 'pks' +    associated_models = {'pks': models.Person} + +    pk = forms.CharField( +        label="", +        required=True, +        widget=widgets.DataTable( +            reverse_lazy('get-person'), PersonSelect, models.Person, +            multiple_select=True, +            source_full=reverse_lazy('get-person-full')), +        validators=[models.valid_ids(models.Person)]) + +    def __init__(self, *args, **kwargs): +        super(MultiSearchForm, self).__init__(*args, **kwargs) +        self.fields['pk'].required = True +        self.fields[self.pk_key] = self.fields.pop('pk') + +  class QAPersonFormMulti(QAForm):      form_admin_name = _(u"Person - Quick action - Modify")      form_slug = "person-quickaction-modify" diff --git a/ishtar_common/templates/ishtar/wizard/confirm_wizard.html b/ishtar_common/templates/ishtar/wizard/confirm_wizard.html index e78a2f4a6..56887d28b 100644 --- a/ishtar_common/templates/ishtar/wizard/confirm_wizard.html +++ b/ishtar_common/templates/ishtar/wizard/confirm_wizard.html @@ -15,6 +15,7 @@    </div>    {% endblock %}    {% block "detailed_informations" %} +  {% block "cards" %}    {% for form_label, form_data in datas %}    <div class="card"> @@ -32,8 +33,8 @@      </div>    </div> -    {% endfor %} +  {% endblock "cards" %}    {{wizard.management_form}}    {% if not wizard.form.is_hidden %}    <table> diff --git a/ishtar_common/templates/ishtar/wizard/delete_wizard.html b/ishtar_common/templates/ishtar/wizard/delete_wizard.html new file mode 100644 index 000000000..82e074eae --- /dev/null +++ b/ishtar_common/templates/ishtar/wizard/delete_wizard.html @@ -0,0 +1,42 @@ +{% extends "ishtar/wizard/confirm_wizard.html" %} +{% load i18n %} +{% load range %} +{% block "warning_message" %} +<div class="alert alert-danger"> +    <p><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> +    {% if current_objs and current_objs.1 %} +    {% trans "Are you sure to want to delete theses items?" %} +    <ul>{% for obj in current_objs %} +        <li>{{obj}}</li> +    {% endfor %}</ul> +    {% else %} +    {% trans "Are you sure to want to delete this item?" %}{% endif %} +    </p> +    <p>{% trans "No rollback is possible. Be careful to scroll to the end of page to check every piece of information." %}</p> +</div> +{% endblock %} + +{% block "cards" %} +{% for form_label, form_data in datas %} + +<div class="card"> +    {% if form_label %} +    <div class="card-header"> +        {{form_label}} +    </div>{% endif %} +    <div class="card-body"> +        {% if current_objs and current_objs.1 %}{% for current_object in current_objs %}{% if forloop.counter == forloop.parentloop.counter %} +        {% block "detailled_extra_info" %} +        {% endblock %} +        {% endif %}{% endfor %}{% endif %} +        <table class='table'> +            {% for data in form_data %} +            <tr{% if data.2 %} class='{{data.2}}'{%endif%}><th>{{data.0}}</th><td>{{data.1}}</td></tr> +            {% endfor %} +        </table> + +    </div> +</div> + +{% endfor %} +{% endblock "cards" %} diff --git a/ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html b/ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html index 6d1f06bd1..27595286b 100644 --- a/ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html +++ b/ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html @@ -1,6 +1,6 @@ -{% extends "ishtar/wizard/confirm_wizard.html" %} +{% extends "ishtar/wizard/delete_wizard.html" %}  {% load i18n %} -{% block "extra_informations" %} +{% block "detailled_extra_info" %}  {% if current_object.file_responsability.count %}  <h3>{% trans "In charge of archaeological files" %}</h3> diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 0f0854720..0f2fe1276 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -164,7 +164,7 @@ def person_modify(request, pk):  person_deletion_wizard = wizards.PersonDeletionWizard.as_view( -    [('selec-person_deletion', forms.PersonFormSelection), +    [('selec-person_deletion', forms.PersonFormMultiSelection),       ('final-person_deletion', FinalDeleteForm)],      label=_(u"Person deletion"),      url_name='person_deletion',) diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 3cdcbc63d..65a37a860 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -38,7 +38,7 @@ from django.db.models.fields import NOT_PROVIDED  from django.http import HttpResponseRedirect, Http404  from django.forms import ValidationError -from django.shortcuts import redirect, render +from django.shortcuts import redirect, render, reverse  from django.template import loader  from django.utils.translation import ugettext_lazy as _  from django.utils.safestring import mark_safe @@ -112,6 +112,7 @@ class Wizard(IshtarWizard):      storage_name = 'formtools.wizard.storage.session.SessionStorage'      wizard_done_template = 'ishtar/wizard/wizard_done.html'      wizard_done_window = '' +    redirect_url = None      wizard_confirm = 'ishtar/wizard/confirm_wizard.html'      wizard_templates = {}      filter_owns = {} @@ -1508,7 +1509,7 @@ class DocumentSearch(SearchWizard):  class DeletionWizard(Wizard):      def __init__(self, *args, **kwargs):          if (not hasattr(self, 'fields') or not self.fields) and \ -           (hasattr(self, 'model') and hasattr(self.model, 'TABLE_COLS')): +                (hasattr(self, 'model') and hasattr(self.model, 'TABLE_COLS')):              self.fields = self.model.TABLE_COLS          assert self.model          return super(DeletionWizard, self).__init__(*args, **kwargs) @@ -1563,6 +1564,107 @@ class DeletionWizard(Wizard):              self.request, 'ishtar/wizard/wizard_delete_done.html', {}) +class MultipleItemWizard(Wizard): +    main_item_select_keys = ('selec-',) +    current_object_key = "pks" + +    def get_current_objects(self): +        current_objs = [] +        for key in self.main_item_select_keys: +            main_form_key = key + self.url_name +            try: +                pks = self.session_get_value(main_form_key, +                                             self.current_object_key) +                if pks: +                    for pk in pks.split(","): +                        current_objs.append(self.model.objects.get(pk=int(pk))) +            except(TypeError, ValueError, ObjectDoesNotExist): +                pass +        return current_objs + + +class MultipleDeletionWizard(MultipleItemWizard): +    def __init__(self, *args, **kwargs): +        if (not hasattr(self, 'fields') or not self.fields) and \ +           (hasattr(self, 'model') and hasattr(self.model, 'TABLE_COLS')): +            self.fields = self.model.TABLE_COLS +        assert self.model +        return super(MultipleDeletionWizard, self).__init__(*args, **kwargs) + +    def get_formated_datas(self, forms): +        datas = super(MultipleDeletionWizard, self).get_formated_datas(forms) +        self.current_objs = [] +        for form in forms: +            if not hasattr(form, "cleaned_data"): +                continue +            for key in form.cleaned_data: +                if key == 'pks': +                    model = form.associated_models['pks'] +                    pks = form.cleaned_data["pks"].split(",") +                    for pk in pks: +                        try: +                            self.current_objs.append(model.objects.get(pk=pk)) +                        except model.DoesNotExist: +                            continue +        if not self.current_objs: +            return datas +        full_res = [] +        for current_obj in self.current_objs: +            res = {} +            for field in self.model._meta.get_fields(): +                if field.name not in self.fields: +                    continue +                value = getattr(current_obj, field.name) +                if not value: +                    continue +                label = "" +                if hasattr(field, 'verbose_name'): +                    label = field.verbose_name +                if hasattr(value, 'all'): +                    if not label and hasattr(field, 'related_model'): +                        label = field.related_model._meta.verbose_name_plural +                    value = ", ".join([str(item) for item in value.all()]) +                    if not value: +                        continue +                else: +                    value = str(value) +                res[field.name] = (label, value, '') +            full_res.append(res) +        if not datas and self.fields: +            datas = [['', []]] +        datas = [] +        for idx, res in enumerate(full_res): +            data = [] +            for field in self.fields: +                if field in res: +                    data.append(res[field]) +            datas.append((str(self.current_objs[idx]), data)) +        return datas + +    def get_context_data(self, form, **kwargs): +        data = super(MultipleDeletionWizard, self).get_context_data(form, +                                                                    **kwargs) +        data["current_objs"] = self.get_current_objects() +        return data + +    def done(self, form_list, **kwargs): +        objs = self.get_current_objects() +        lbls = [] +        for obj in objs: +            lbls.append(str(obj)) +            try: +                obj.delete() +            except ObjectDoesNotExist: +                pass +        msg = '<i class="fa fa-trash" aria-hidden="true"></i>  ' +        msg += str(_("{} deleted.")).format(" ; ".join(lbls)) +        messages.add_message(self.request, messages.INFO, msg) +        if self.redirect_url: +            return HttpResponseRedirect(reverse(self.redirect_url)) +        return render( +            self.request, 'ishtar/wizard/wizard_delete_done.html', {}) + +  class ClosingWizard(Wizard):      # "close" an item      # to be define in the overloaded class @@ -1628,9 +1730,10 @@ class PersonModifWizard(PersonWizard):          'identity-person_modification': "ishtar/wizard/wizard_person.html"} -class PersonDeletionWizard(DeletionWizard): +class PersonDeletionWizard(MultipleDeletionWizard):      model = models.Person      fields = model.TABLE_COLS +    redirect_url = "person_search"      wizard_templates = {          'final-person_deletion': 'ishtar/wizard/wizard_person_deletion.html'} | 
