diff options
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 |
commit | c5e794a0f21d5ebd8db764ae34d8026cf5caf365 (patch) | |
tree | 63a7d4c8f7cb34c6f4c0c9089bfafce00a46dfd8 /archaeological_finds | |
parent | 8d6714d0c71137b5b6f05723e9b336f67e10ee09 (diff) | |
download | Ishtar-c5e794a0f21d5ebd8db764ae34d8026cf5caf365.tar.bz2 Ishtar-c5e794a0f21d5ebd8db764ae34d8026cf5caf365.zip |
Quick actions: generic urls, views and forms
Diffstat (limited to 'archaeological_finds')
-rw-r--r-- | archaeological_finds/forms.py | 112 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 22 | ||||
-rw-r--r-- | archaeological_finds/urls.py | 15 | ||||
-rw-r--r-- | archaeological_finds/views.py | 52 |
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'])) |