diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-05-29 12:05:49 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-06-17 13:21:28 +0200 |
commit | 0e30743556cdf9b6f8268cb8e24b24abf76a2e2b (patch) | |
tree | d4d6c917902002f8c4a86b3c9f65ecacad12d7ec /archaeological_finds | |
parent | 81ee5b2f6d5bb4868128296108a0e99074d1ca72 (diff) | |
download | Ishtar-0e30743556cdf9b6f8268cb8e24b24abf76a2e2b.tar.bz2 Ishtar-0e30743556cdf9b6f8268cb8e24b24abf76a2e2b.zip |
QA: duplicate find
Diffstat (limited to 'archaeological_finds')
-rw-r--r-- | archaeological_finds/forms.py | 25 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 26 | ||||
-rw-r--r-- | archaeological_finds/templates/ishtar/forms/qa_find_duplicate.html | 46 | ||||
-rw-r--r-- | archaeological_finds/tests.py | 36 | ||||
-rw-r--r-- | archaeological_finds/urls.py | 4 | ||||
-rw-r--r-- | archaeological_finds/views.py | 29 |
6 files changed, 162 insertions, 4 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 58c10971a..129a1446e 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -726,6 +726,31 @@ class QAFindBasketForm(IshtarForm): basket.items.add(item) +class QAFindDuplicateForm(IshtarForm): + label = forms.CharField(label=_("Free ID"), max_length=None, required=True) + denomination = forms.CharField(label=_("Denomination"), max_length=None, + required=False) + # modify = forms.BooleanField(label=_("Edit the new find"), required=False) + + def __init__(self, *args, **kwargs): + self.user = None + if 'user' in kwargs: + self.user = kwargs.pop('user') + if hasattr(self.user, 'ishtaruser'): + self.user = self.user.ishtaruser + self.find = kwargs.pop('items')[0] + super(QAFindDuplicateForm, self).__init__(*args, **kwargs) + self.fields['label'].initial = self.find.label + str( + _(u" - duplicate")) + self.fields['denomination'].initial = self.find.denomination or "" + + def save(self): + return self.find.duplicate( + self.user, duplicate_for_treatment=False, + data={"label": self.cleaned_data["label"], + "denomination": self.cleaned_data["denomination"]}) + + class QAFindbasketDuplicateForm(IshtarForm): label = forms.CharField(label="", max_length=None, required=True) diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index ad9e2a822..4f28b977c 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1385,6 +1385,10 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, QUICK_ACTIONS = [ QA_EDIT, QuickAction( + url="find-qa-duplicate", icon_class="fa fa-clone", + text=_(u"Duplicate"), target="one", + rights=['change_find', 'change_own_find']), + QuickAction( url="find-qa-basket", icon_class="fa fa-shopping-basket", text=_(u"Basket"), target="many", rights=['change_find', 'change_own_find']), @@ -1686,6 +1690,8 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, can_edit_find = self.can_do(request, 'change_find') if can_edit_find: actions += [ + (reverse("find-qa-duplicate", args=[self.pk]), + _("Duplicate"), "fa fa-clone", "", "", True), (reverse("find-qa-basket", args=[self.pk]), _(u"Add to basket"), "fa fa-shopping-basket", "", "", True), @@ -1873,13 +1879,14 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, base_finds__context_record__operation__pk=operation_id) @classmethod - def get_total_number(cls, fltr={}): + def get_total_number(cls, fltr=None): q = cls.objects if fltr: q = q.filter(**fltr) return q.filter(downstream_treatment__isnull=True).count() - def duplicate(self, user, copy_datings=True): + def duplicate(self, user, copy_datings=True, duplicate_for_treatment=True, + data=None): model = self.__class__ new = model.objects.get(pk=self.pk) @@ -1889,8 +1896,13 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, # item will be created on save if field.name in PRIVATE_FIELDS: setattr(new, field.name, None) - new.order = self.order + 1 - new.history_order = user + new.order = self.order + if duplicate_for_treatment: + new.order += 1 + new.history_user = user + if data: + for k in data: + setattr(new, k, data[k]) new.save() # m2m fields @@ -1913,6 +1925,12 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, for val in getattr(self, field).all(): if val not in getattr(new, field).all(): getattr(new, field).add(val) + if not duplicate_for_treatment: + bf = self.get_first_base_find() + new.base_finds.clear() + if bf: + new.base_finds.add(bf.duplicate( + user=user, data={"label": new.label, "external_id": None})) return new @classmethod diff --git a/archaeological_finds/templates/ishtar/forms/qa_find_duplicate.html b/archaeological_finds/templates/ishtar/forms/qa_find_duplicate.html new file mode 100644 index 000000000..c00c74c31 --- /dev/null +++ b/archaeological_finds/templates/ishtar/forms/qa_find_duplicate.html @@ -0,0 +1,46 @@ +{% extends "ishtar/forms/qa_base.html" %} +{% load i18n inline_formset table_form %} + +{% block main_form %} +{% if form.non_field_errors %} +<div class="alert alert-danger" role="alert"> + {{form.non_field_errors}} +</div> +{% endif %} +{% if operation %} +<div class="alert alert-info"> + {% trans "The new find will have a new base find created. Instead of this action use a division treatment if the new find is from the same base find (share the same field data)." %} +</div> +<div class="form-row"> + <div class="form-group col-lg-12 required full-width"> + <label>{% trans "Operation" %}{% trans ":" %}</label> + {{operation}} + </div> +</div> +<div class="form-row"> + <div class="form-group col-lg-12 required full-width"> + <label>{% trans "Context record" %}{% trans ":" %}</label> + {{context_record }} + </div> +</div> +{% endif %} +{% with force_large_col=True %} +<div class="form-row"> + {% with form.label as field %} + {% include "blocks/bs_field_snippet.html" %} + {% endwith %} +</div> +<div class="form-row"> + {% with form.denomination as field %} + {% include "blocks/bs_field_snippet.html" %} + {% endwith %} +</div> +{% endwith %} +{% comment %} +<p> + <label for="id_modify">{% trans "Edit the duplicated find" %}{% trans ":" %}</label> + <input type="checkbox" name="modify" id="id_modify"> +</p> +{% endcomment %} +{% endblock %} + diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index 806696d4c..acd86727b 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -1084,6 +1084,42 @@ class FindQATest(FindInit, TestCase): self.alt_user.user_permissions.add(Permission.objects.get( codename='change_find')) + def test_duplicate(self): + find = self.finds[0] + default_desc = "Description for duplicate" + find.description = default_desc + find.save() + c = Client() + url = reverse('find-qa-duplicate', args=[find.pk]) + response = c.get(url) + self.assertRedirects(response, '/') + + c = Client() + c.login(username=self.username, password=self.password) + response = c.get(url) + self.assertEqual(response.status_code, 200) + + c = Client() + c.login(username=self.alt_username, password=self.alt_password) + response = c.get(url) + self.assertEqual(response.status_code, 200) + + data = { + "denomination": "clone", + "label": "clone - free id" + } + nb_find = models.Find.objects.count() + nb_bf = models.BaseFind.objects.count() + response = c.post(url, data) + self.assertEqual(response.status_code, 302) # success redirect + self.assertEqual(models.Find.objects.count(), nb_find + 1) + self.assertEqual(models.BaseFind.objects.count(), nb_bf + 1) + new = models.Find.objects.order_by('-pk').all()[0] + self.assertEqual(new.description, default_desc) + new_bf = models.BaseFind.objects.order_by('-pk').all()[0] + base_bf = find.get_first_base_find() + self.assertEqual(new_bf.context_record, base_bf.context_record) + def test_bulk_update(self): c = Client() pks = u"{}-{}".format(self.finds[0].pk, self.finds[1].pk) diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index 7b70f2296..0f86a363e 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -43,6 +43,10 @@ urlpatterns = [ views.find_deletion_wizard), name='find_deletion'), url(r'find_modify/(?P<pk>.+)/$', views.find_modify, name='find_modify'), + url(r'^find-qa-duplicate/(?P<pks>[0-9-]+)?/$', + check_rights(['change_find', 'change_own_find'])( + views.QAFindDuplicateFormView.as_view()), + name='find-qa-duplicate'), url(r'get-findbasket/$', views.get_find_basket, name='get-findbasket'), url(r'get-findbasket-write/$', views.get_find_basket_for_write, diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index b8a23367b..ed0389cff 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -936,6 +936,35 @@ class QAFindBasketFormView(QAItemForm): return HttpResponseRedirect(reverse("success")) +class QAFindDuplicateFormView(QAItemForm): + template_name = 'ishtar/forms/qa_find_duplicate.html' + model = models.Find + page_name = _(u"Duplicate") + form_class = forms.QAFindDuplicateForm + + def get_quick_action(self): + return models.Find.QUICK_ACTIONS[1] + + def get_form_kwargs(self): + kwargs = super(QAFindDuplicateFormView, self).get_form_kwargs() + kwargs['user'] = self.request.user + return kwargs + + def form_valid(self, form): + form.save() + return HttpResponseRedirect(reverse("success")) + + def get_context_data(self, **kwargs): + data = super(QAFindDuplicateFormView, self).get_context_data( + **kwargs) + data['action_name'] = _(u"Duplicate") + bf = self.items[0].get_first_base_find() + if bf: + data['context_record'] = bf.context_record + data['operation'] = bf.context_record.operation + return data + + class QAFindTreatmentFormView(QAItemForm): template_name = 'ishtar/forms/qa_find_treatment.html' model = models.Find |