summaryrefslogtreecommitdiff
path: root/archaeological_finds
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2018-09-05 10:41:24 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2018-10-24 12:06:08 +0200
commitc5e794a0f21d5ebd8db764ae34d8026cf5caf365 (patch)
tree63a7d4c8f7cb34c6f4c0c9089bfafce00a46dfd8 /archaeological_finds
parent8d6714d0c71137b5b6f05723e9b336f67e10ee09 (diff)
downloadIshtar-c5e794a0f21d5ebd8db764ae34d8026cf5caf365.tar.bz2
Ishtar-c5e794a0f21d5ebd8db764ae34d8026cf5caf365.zip
Quick actions: generic urls, views and forms
Diffstat (limited to 'archaeological_finds')
-rw-r--r--archaeological_finds/forms.py112
-rw-r--r--archaeological_finds/models_finds.py22
-rw-r--r--archaeological_finds/urls.py15
-rw-r--r--archaeological_finds/views.py52
4 files changed, 186 insertions, 15 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py
index fbcc32013..a7fc0bc02 100644
--- a/archaeological_finds/forms.py
+++ b/archaeological_finds/forms.py
@@ -52,7 +52,7 @@ from bootstrap_datepicker.widgets import DatePicker
from ishtar_common import widgets
from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \
FloatField, reverse_lazy, TableSelect, get_now, FinalForm, \
- ManageOldType, FieldType, IshtarForm, FormHeader
+ ManageOldType, FieldType, IshtarForm, FormHeader, QAForm
from ishtar_common.forms_common import get_town_field
from ishtar_common.models import valid_id, valid_ids, get_current_profile, \
SpatialReferenceSystem, Area, OperationType
@@ -79,6 +79,7 @@ __all__ = [
'check_treatment', 'ResultFindForm', 'ResultFindFormSet',
'FindDeletionForm', 'UpstreamFindFormSelection', 'NewFindBasketForm',
'SelectFindBasketForm', 'DeleteFindBasketForm', 'FindBasketAddItemForm',
+ 'QAFindFormSingle', 'QAFindFormMulti'
]
logger = logging.getLogger(__name__)
@@ -207,24 +208,24 @@ class FindForm(CustomForm, ManageOldType):
dimensions_comment = forms.CharField(
label=_(u"Dimensions comment"), required=False, widget=forms.Textarea)
- HEADERS['get_first_base_find__topographic_localisation'] = FormHeader(
+ HEADERS['get_first_base_find__x'] = FormHeader(
_(u"Coordinates"))
- get_first_base_find__topographic_localisation = forms.CharField(
- label=_(u"Point of topographic reference"),
- required=False, max_length=120
- )
get_first_base_find__x = forms.FloatField(label=_(u"X"), required=False)
- get_first_base_find__y = forms.FloatField(label=_(u"Y"), required=False)
- get_first_base_find__z = forms.FloatField(label=_(u"Z"), required=False)
- get_first_base_find__spatial_reference_system = \
- forms.ChoiceField(label=_(u"Spatial Reference System"), required=False,
- choices=[])
get_first_base_find__estimated_error_x = \
forms.FloatField(label=_(u"Estimated error for X"), required=False)
+ get_first_base_find__y = forms.FloatField(label=_(u"Y"), required=False)
get_first_base_find__estimated_error_y = \
forms.FloatField(label=_(u"Estimated error for Y"), required=False)
+ get_first_base_find__z = forms.FloatField(label=_(u"Z"), required=False)
get_first_base_find__estimated_error_z = \
forms.FloatField(label=_(u"Estimated error for Z"), required=False)
+ get_first_base_find__spatial_reference_system = \
+ forms.ChoiceField(label=_(u"Spatial Reference System"), required=False,
+ choices=[])
+ get_first_base_find__topographic_localisation = forms.CharField(
+ label=_(u"Point of topographic reference"),
+ required=False, max_length=120
+ )
HEADERS['checked_type'] = FormHeader(_(u"Sheet"))
checked_type = forms.ChoiceField(label=_(u"Check"), required=False)
@@ -315,6 +316,95 @@ class FindForm(CustomForm, ManageOldType):
return self.cleaned_data
+QAHeaders = {
+ 'description': FormHeader(_(u"Description")),
+ 'checked_type': FormHeader(_(u"Sheet"))
+}
+
+
+class QAFindFormMulti(QAForm):
+ form_admin_name = _(u"Find - Quick action - Modify")
+ form_slug = "find-quickaction-modify"
+ base_models = ['get_first_base_find', 'object_types', 'material_types',
+ 'communicabilities']
+ associated_models = {
+ 'material_types': models.MaterialType,
+ 'object_types': models.ObjectType,
+ 'communicabilities': models.CommunicabilityType,
+ 'checked_type': models.CheckedType,
+ }
+
+ MULTI = True
+ REPLACE_FIELDS = [
+ 'manufacturing_place', 'checked_type', 'check_date'
+ ]
+
+ HEADERS = QAHeaders.copy()
+
+ description = forms.CharField(label=_(u"Description"),
+ widget=forms.Textarea, required=False)
+ material_types = widgets.Select2MultipleField(
+ label=_(u"Material types"), required=False
+ )
+ object_types = widgets.Select2MultipleField(
+ label=_(u"Object types"), required=False,
+ )
+ decoration = forms.CharField(
+ label=_(u"Decoration"), widget=forms.Textarea,
+ required=False)
+ inscription = forms.CharField(
+ label=_(u"Inscription"), widget=forms.Textarea,
+ required=False)
+ manufacturing_place = forms.CharField(
+ label=_(u"Manufacturing place"), required=False)
+ communicabilities = widgets.Select2MultipleField(
+ label=_(u"Communicability"), required=False
+ )
+ comment = forms.CharField(
+ label=_(u"Comment"), required=False,
+ widget=forms.Textarea)
+ dating_comment = forms.CharField(
+ label=_(u"Comment on dating"), required=False,
+ widget=forms.Textarea)
+
+ checked_type = forms.ChoiceField(label=_(u"Check"), required=False)
+ check_date = forms.DateField(
+ initial=get_now, label=_(u"Check date"), widget=DatePicker)
+
+ TYPES = [
+ FieldType('material_types', models.MaterialType, is_multiple=True),
+ FieldType('object_types', models.ObjectType, is_multiple=True),
+ FieldType('communicabilities', models.CommunicabilityType,
+ is_multiple=True),
+ FieldType('checked_type', models.CheckedType, is_multiple=True),
+ ]
+
+
+class QAFindFormSingle(QAFindFormMulti):
+ form_admin_name = _(u"Find - Quick action - Modify single")
+ form_slug = "find-quickaction-modifysingle"
+ HEADERS = QAHeaders.copy()
+ HEADERS['label'] = FormHeader(_(u"Identification"))
+
+ label = forms.CharField(
+ label=_(u"Free ID"),
+ validators=[validators.MaxLengthValidator(60)])
+ denomination = forms.CharField(label=_(u"Denomination"), required=False)
+ previous_id = forms.CharField(label=_("Previous ID"), required=False)
+ get_first_base_find__excavation_id = forms.CharField(
+ label=_(u"Excavation ID"), required=False)
+ museum_id = forms.CharField(label=_(u"Museum ID"), required=False)
+ seal_number = forms.CharField(label=_(u"Seal number"), required=False)
+ mark = forms.CharField(label=_(u"Mark"), required=False)
+
+ def __init__(self, *args, **kwargs):
+ super(QAFindFormSingle, self).__init__(*args, **kwargs)
+ if not self.items or \
+ not self.items[0].get_first_base_find(
+ ).context_record.operation.operation_type.judiciary:
+ self.fields.pop('seal_number')
+
+
class PreservationForm(CustomForm, ManageOldType):
form_label = _("Preservation")
form_admin_name = _(u"Find - 030 - Preservation")
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 1ef9d5846..0911317f2 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -39,7 +39,7 @@ from ishtar_common.models import Document, GeneralType, \
HierarchicalType, BaseHistorizedItem, ShortMenuItem, LightHistorizedItem, \
HistoricalRecords, OwnPerms, Person, Basket, post_save_cache, \
ValueGetter, get_current_profile, IshtarSiteProfile, PRIVATE_FIELDS, \
- SpatialReferenceSystem, BulkUpdatedItem, ExternalIdManager
+ SpatialReferenceSystem, BulkUpdatedItem, ExternalIdManager, QuickAction
from archaeological_operations.models import AdministrativeAct, Operation
from archaeological_context_records.models import ContextRecord, Dating
@@ -605,7 +605,7 @@ class FBulkView(object):
class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
- ShortMenuItem):
+ MainItem):
EXTERNAL_ID_KEY = 'find_external_id'
SHOW_URL = 'show-find'
SLUG = 'find'
@@ -878,6 +878,24 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
"remarkabilities__label", "material_types__label"]
objects = ExternalIdManager()
+ QA_EDIT = QuickAction(
+ url="find-qa-bulk-update", icon_class="fa fa-pencil",
+ text=_(u"Bulk update"), target="many",
+ rights=['change_find', 'change_own_find'])
+
+ QUICK_ACTIONS = [
+ QA_EDIT,
+ QuickAction(
+ url="find-qa-packaging", icon_class="fa fa-gift",
+ text=_(u"Packaging"), target="many", rights=['change_warehouse'],
+ module='warehouse'
+ ),
+ QuickAction(
+ url="find-qa-basket", icon_class="fa fa-shopping-basket",
+ text=_(u"Basket"), target="many",
+ rights=['change_find', 'change_own_find']),
+ ]
+
# fields
base_finds = models.ManyToManyField(BaseFind, verbose_name=_(u"Base find"),
related_name='find')
diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py
index 9a71c66d8..39da45532 100644
--- a/archaeological_finds/urls.py
+++ b/archaeological_finds/urls.py
@@ -71,6 +71,21 @@ urlpatterns = [
check_rights(['change_find', 'change_own_find'])(
views.DeleteFindBasketView.as_view()), name='delete_findbasket'),
+ url(r'^find-qa-bulk-update/(?P<pks>[0-9-]+)?/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.QAFindForm.as_view()),
+ name='find-qa-bulk-update'),
+
+ url(r'^find-qa-packaging/(?P<pks>[0-9-]+)?/$',
+ check_rights(['change_warehouse'])(
+ views.FindBasketAddItemView.as_view()),
+ name='find-qa-packaging'),
+ url(r'^find-qa-basket/(?P<pks>[0-9-]+)?/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.FindBasketAddItemView.as_view()),
+ name='find-qa-basket'),
+
+
url(r'^treatment_creation/(?P<step>.+)?$',
check_rights(['change_find', 'change_own_find'])(
views.treatment_creation_wizard), name='treatment_creation'),
diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py
index 6c6d9fff9..034e1994f 100644
--- a/archaeological_finds/views.py
+++ b/archaeological_finds/views.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2018 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -21,7 +21,7 @@ import json
from django.core.urlresolvers import reverse
from django.db.models import Q
-from django.http import HttpResponseRedirect, HttpResponse
+from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView
@@ -594,3 +594,51 @@ def reset_wizards(request):
'treatmentfle_admacttreatmentfle_deletion'),
):
wizard_class.session_reset(request, url_name)
+
+
+class QAItemEditForm(IshtarMixin, LoginRequiredMixin, FormView):
+ template_name = 'ishtar/qa_form.html'
+ model = None
+ form_class = None
+ form_class_multi = None
+
+ def dispatch(self, request, *args, **kwargs):
+ assert self.model
+ pks = [int(pk) for pk in kwargs.get('pks').split('-')]
+ self.items = list(self.model.objects.filter(pk__in=pks))
+ if not self.items:
+ raise Http404()
+
+ # check availability
+ if not self.model.QA_EDIT.is_available(
+ user=request.user, session=request.session):
+ for item in self.items:
+ if not self.model.QA_EDIT.is_available(
+ user=request.user, session=request.session, obj=item):
+ raise Http404()
+
+ return super(QAItemEditForm, self).dispatch(request, *args, **kwargs)
+
+ def get_form_class(self):
+ if len(self.items) > 1:
+ return self.form_class_multi
+ return self.form_class
+
+ def get_form_kwargs(self):
+ kwargs = super(QAItemEditForm, self).get_form_kwargs()
+ kwargs['items'] = self.items
+ return kwargs
+
+
+class QAFindForm(QAItemEditForm):
+ model = models.Find
+ form_class = QAFindFormSingle
+ form_class_multi = QAFindFormMulti
+
+ def get_success_url(self, basket):
+ return reverse('select_itemsinbasket',
+ kwargs={'pk': basket})
+
+ def form_valid(self, form):
+ return HttpResponseRedirect(self.get_success_url(
+ form.cleaned_data['basket']))