summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_finds/forms.py4
-rw-r--r--ishtar_common/forms.py2
-rw-r--r--ishtar_common/forms_common.py22
-rw-r--r--ishtar_common/templates/ishtar/wizard/confirm_wizard.html3
-rw-r--r--ishtar_common/templates/ishtar/wizard/delete_wizard.html42
-rw-r--r--ishtar_common/templates/ishtar/wizard/wizard_person_deletion.html4
-rw-r--r--ishtar_common/views.py2
-rw-r--r--ishtar_common/wizards.py109
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>&nbsp;&nbsp;'
+ 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'}