diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-09-10 20:49:13 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-09-10 20:49:13 +0200 |
commit | 3dae10a792d49d685debfe52eb7d61b9a6dc93f9 (patch) | |
tree | 45f1d910b67a30e44015735581ec9cdc6db51cdf | |
parent | 58178a04b3e716a063b1c457018aafe28e5107dd (diff) | |
download | Ishtar-3dae10a792d49d685debfe52eb7d61b9a6dc93f9.tar.bz2 Ishtar-3dae10a792d49d685debfe52eb7d61b9a6dc93f9.zip |
QA: lock/unlock (sites, operations, context records, finds, containers, warehouses)
-rw-r--r-- | archaeological_context_records/models.py | 14 | ||||
-rw-r--r-- | archaeological_context_records/urls.py | 4 | ||||
-rw-r--r-- | archaeological_context_records/views.py | 9 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 6 | ||||
-rw-r--r-- | archaeological_finds/urls.py | 4 | ||||
-rw-r--r-- | archaeological_finds/views.py | 7 | ||||
-rw-r--r-- | archaeological_operations/forms.py | 2 | ||||
-rw-r--r-- | archaeological_operations/models.py | 22 | ||||
-rw-r--r-- | archaeological_operations/urls.py | 8 | ||||
-rw-r--r-- | archaeological_operations/views.py | 12 | ||||
-rw-r--r-- | archaeological_warehouse/forms.py | 12 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 20 | ||||
-rw-r--r-- | archaeological_warehouse/urls.py | 8 | ||||
-rw-r--r-- | archaeological_warehouse/views.py | 12 | ||||
-rw-r--r-- | ishtar_common/forms.py | 6 | ||||
-rw-r--r-- | ishtar_common/forms_common.py | 21 | ||||
-rw-r--r-- | ishtar_common/views.py | 11 |
17 files changed, 157 insertions, 21 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 875a48019..dc8409b39 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -33,14 +33,13 @@ from django.utils.text import slugify from ishtar_common.utils import cached_label_changed, \ m2m_historization_changed, post_save_geo -from ishtar_common.model_managers import ExternalIdManager from ishtar_common.models import Document, GeneralType, \ BaseHistorizedItem, HistoricalRecords, OwnPerms, ShortMenuItem, \ GeneralRelationType, GeneralRecordRelations, post_delete_record_relation,\ post_save_cache, ValueGetter, BulkUpdatedItem, \ RelationItem, Town, get_current_profile, document_attached_changed, \ HistoryModel, SearchAltName, GeoItem, QRCodeItem, SearchVectorConfig, \ - DocumentItem + DocumentItem, MainItem, QuickAction from archaeological_operations.models import Operation, Period, Parcel, \ ArchaeologicalSite from ishtar_common.model_managers import UUIDModelManager @@ -292,7 +291,7 @@ class CRBulkView(object): class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem, - QRCodeItem, GeoItem, OwnPerms, ValueGetter, ShortMenuItem, + QRCodeItem, GeoItem, OwnPerms, ValueGetter, MainItem, RelationItem): SLUG = 'contextrecord' APP = "archaeological-context-records" @@ -452,6 +451,15 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem, "cached_related_context_records"] DOWN_MODEL_UPDATE = ["base_finds"] + QA_LOCK = QuickAction( + url="contextrecord-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_contextrecord', 'change_own_contextrecord'] + ) + QUICK_ACTIONS = [ + QA_LOCK + ] + history = HistoricalRecords(bases=[HistoryModel]) objects = UUIDModelManager() diff --git a/archaeological_context_records/urls.py b/archaeological_context_records/urls.py index 0b46f4de8..ccab8cacb 100644 --- a/archaeological_context_records/urls.py +++ b/archaeological_context_records/urls.py @@ -87,4 +87,8 @@ urlpatterns = [ views.QAOperationContextRecordView.as_view()), name='operation-qa-contextrecord'), + url(r'^contextrecord-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QAContextRecordLockView.as_view(), name='contextrecord-qa-lock', + kwargs={"model": models.ContextRecord}), + ] diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index 794cb5592..1aa691cff 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -34,7 +34,8 @@ from archaeological_operations.views import site_extra_context from archaeological_context_records import forms from ishtar_common.utils import put_session_message -from ishtar_common.views import IshtarMixin, LoginRequiredMixin, QAItemForm +from ishtar_common.views import IshtarMixin, LoginRequiredMixin, QAItemForm, \ + QABaseLockView from ishtar_common.views_item import display_item, get_item, show_item, \ revert_item from archaeological_context_records import wizards @@ -228,3 +229,9 @@ class QAOperationContextRecordView(QAItemForm): def form_valid(self, form): form.save(self.items) return HttpResponseRedirect(reverse("success")) + + +class QAContextRecordLockView(QABaseLockView): + model = models.ContextRecord + base_url = "contextrecord-qa-lock" + diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 9b134bceb..bc6f440bc 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1399,6 +1399,11 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, url="find-qa-bulk-update", icon_class="fa fa-pencil", text=_(u"Bulk update"), target="many", rights=['change_find', 'change_own_find']) + QA_LOCK = QuickAction( + url="find-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_find', 'change_own_find'] + ) QUICK_ACTIONS = [ QA_EDIT, @@ -1416,6 +1421,7 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, rights=['change_find', 'change_own_find'], module='warehouse' ), + QA_LOCK ] UP_MODEL_QUERY = { "operation": (pgettext_lazy("key for text search", "operation"), diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index 8e01a2931..b36c25888 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -142,6 +142,10 @@ urlpatterns = [ views.QAFindTreatmentFormView.as_view()), name='find-qa-packaging'), + url(r'^find-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QAFindLockView.as_view(), name='find-qa-lock', + kwargs={"model": models.Find}), + 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 e5119b9f3..1b49c8f13 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -47,7 +47,7 @@ from archaeological_operations.forms import FinalAdministrativeActDeleteForm from archaeological_finds import forms from ishtar_common.views import get_autocomplete_generic, IshtarMixin, \ - LoginRequiredMixin, QAItemEditForm, QAItemForm + LoginRequiredMixin, QAItemEditForm, QAItemForm, QABaseLockView from ishtar_common.views_item import display_item, get_item, show_item, \ revert_item, get_autocomplete_item, get_autocomplete_queries @@ -1018,6 +1018,11 @@ class QAFindbasketDuplicateFormView(QAItemForm): return data +class QAFindLockView(QABaseLockView): + model = models.Find + base_url = "find-qa-lock" + + class PublicFindAPI(APIView): authentication_classes = (authentication.TokenAuthentication,) permission_classes = (permissions.IsAuthenticated,) diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 1e12c3614..b79447d9f 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -1375,7 +1375,7 @@ class SiteSelect(HistorySelect): self.fields.pop('drassm_number') -class SiteFormSelection(IshtarForm): +class SiteFormSelection(CustomFormSearch): SEARCH_AND_SELECT = True associated_models = {'pk': models.ArchaeologicalSite} currents = {'pk': models.ArchaeologicalSite} diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index c2e4e618b..6a25490d7 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -111,7 +111,7 @@ post_delete.connect(post_save_cache, sender=RecordQualityType) class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, QRCodeItem, - GeoItem, OwnPerms, ValueGetter, ShortMenuItem): + GeoItem, OwnPerms, ValueGetter, MainItem): SLUG = 'site' APP = "archaeological-operations" MODEL = "archaeological-site" @@ -256,6 +256,15 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, QRCodeItem, 'cached_remains'] DOWN_MODEL_UPDATE = ["context_records"] + QA_LOCK = QuickAction( + url="contextrecord-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_contextrecord', 'change_own_contextrecord'] + ) + QUICK_ACTIONS = [ + QA_LOCK + ] + objects = SiteManager() reference = models.CharField(_("Reference"), max_length=200, unique=True) @@ -870,9 +879,14 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, QRCodeItem, QA_EDIT = QuickAction( url="operation-qa-bulk-update", icon_class="fa fa-pencil", text=_(u"Bulk update"), target="many", - rights=['change_operation', 'change_own_operation']) + ) + QA_LOCK = QuickAction( + url="operation-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_operation', 'change_own_operation'] + ) QUICK_ACTIONS = [ - QA_EDIT + QA_EDIT, QA_LOCK ] UP_MODEL_QUERY = { @@ -1284,7 +1298,7 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, QRCodeItem, actions = super(Operation, self).get_extra_actions(request) can_add_cr = self.can_do(request, 'add_contextrecord') - if can_add_cr: + if can_add_cr and not self.locked: actions += [ (reverse('operation-qa-contextrecord', args=[self.pk]), _("Add context record"), "fa fa-plus", diff --git a/archaeological_operations/urls.py b/archaeological_operations/urls.py index 1cb66de6f..38dbe2cbf 100644 --- a/archaeological_operations/urls.py +++ b/archaeological_operations/urls.py @@ -176,4 +176,12 @@ urlpatterns = [ check_rights(['change_operation', 'change_own_operation'])( views.QAOperationForm.as_view()), name='operation-qa-bulk-update-confirm', kwargs={"confirm": True}), + + url(r'^operation-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QAOperationLockView.as_view(), name='operation-qa-lock', + kwargs={"model": models.Operation}), + + url(r'^site-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QASiteLockView.as_view(), name='site-qa-lock', + kwargs={"model": models.ArchaeologicalSite}), ] diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index d8d9f30d5..0d69d72f3 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -52,7 +52,7 @@ from ishtar_common.forms import ClosingDateFormSelection, FinalForm, \ from ishtar_common.models import get_current_profile, IshtarSiteProfile, \ DocumentTemplate from ishtar_common.utils import put_session_message, check_rights_condition -from ishtar_common.views import gen_generate_doc, QAItemEditForm +from ishtar_common.views import gen_generate_doc, QAItemEditForm, QABaseLockView from ishtar_common.views_item import get_item, show_item, revert_item, new_item from ishtar_common.wizards import SearchWizard @@ -581,3 +581,13 @@ def reset_wizards(request): class QAOperationForm(QAItemEditForm): model = models.Operation form_class = QAOperationFormMulti + + +class QAOperationLockView(QABaseLockView): + model = models.Operation + base_url = "operation-qa-lock" + + +class QASiteLockView(QABaseLockView): + model = models.ArchaeologicalSite + base_url = "site-qa-lock" diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py index ecf040a7e..5a558aa45 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -42,7 +42,8 @@ from bootstrap_datepicker.widgets import DatePicker from ishtar_common.forms import name_validator, reverse_lazy, \ get_form_selection, ManageOldType, FinalForm, FormSet, \ - CustomForm, FieldType, HistorySelect, FormHeader, TableSelect + CustomForm, FieldType, HistorySelect, FormHeader, TableSelect, \ + CustomFormSearch from ishtar_common.forms_common import get_town_field from archaeological_finds.forms import FindMultipleFormSelection, \ SelectFindBasketForm @@ -109,7 +110,7 @@ class WarehouseSelect(CustomForm, TableSelect): models.WarehouseType.get_help() -class WarehouseFormSelection(forms.Form): +class WarehouseFormSelection(CustomFormSearch): SEARCH_AND_SELECT = True form_label = _("Warehouse search") associated_models = {'pk': models.Warehouse} @@ -448,12 +449,15 @@ ContainerFormSelection = get_form_selection( 'ContainerFormSelection', _(u"Container search"), 'container', models.Container, ContainerSelect, 'get-container', _(u"You should select a container."), new=True, - new_message=_(u"Add a new container")) + new_message=_(u"Add a new container"), + base_form_select=CustomFormSearch +) MainContainerFormSelection = get_form_selection( 'ContainerFormSelection', _(u"Container search"), 'pk', models.Container, ContainerSelect, 'get-container', - _(u"You should select a container."), gallery=True, map=True + _(u"You should select a container."), gallery=True, map=True, + base_form_select = CustomFormSearch ) diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index a3cbf82e3..96257da3c 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -33,7 +33,7 @@ from ishtar_common.models import Document, GeneralType, get_external_id, \ LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, \ DashboardFormItem, ShortMenuItem, Organization, OrganizationType, \ document_attached_changed, SearchAltName, DynamicRequest, GeoItem, \ - QRCodeItem, SearchVectorConfig, DocumentItem + QRCodeItem, SearchVectorConfig, DocumentItem, QuickAction, MainItem from ishtar_common.model_merging import merge_model_objects from ishtar_common.utils import cached_label_changed, \ cached_label_and_geo_changed @@ -51,7 +51,7 @@ post_delete.connect(post_save_cache, sender=WarehouseType) class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem, - OwnPerms, ShortMenuItem): + OwnPerms, MainItem): SLUG = 'warehouse' APP = "archaeological-warehouse" MODEL = "warehouse" @@ -86,6 +86,13 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem, DOWN_MODEL_UPDATE = ["containers"] CACHED_LABELS = [] + QA_LOCK = QuickAction( + url="warehouse-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_warehouse', 'change_own_warehouse'] + ) + QUICK_ACTIONS = [QA_LOCK] + objects = ExternalIdManager() name = models.CharField(_(u"Name"), max_length=200) @@ -411,7 +418,7 @@ post_delete.connect(post_save_cache, sender=ContainerType) class Container(DocumentItem, LightHistorizedItem, QRCodeItem, GeoItem, - OwnPerms): + OwnPerms, MainItem): SLUG = 'container' APP = "archaeological-warehouse" MODEL = "container" @@ -578,6 +585,13 @@ class Container(DocumentItem, LightHistorizedItem, QRCodeItem, GeoItem, ), } + QA_LOCK = QuickAction( + url="container-qa-lock", icon_class="fa fa-lock", + text=_(u"Lock/Unlock"), target="many", + rights=['change_container', 'change_own_container'] + ) + QUICK_ACTIONS = [QA_LOCK] + objects = ExternalIdManager() # fields diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py index 47058a352..ba1e3342c 100644 --- a/archaeological_warehouse/urls.py +++ b/archaeological_warehouse/urls.py @@ -68,6 +68,10 @@ urlpatterns = [ url(r'warehouse-modify/(?P<pk>.+)/$', views.warehouse_modify, name='warehouse_modify'), + url(r'^warehouse-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QAWarehouseLockView.as_view(), name='warehouse-qa-lock', + kwargs={"model": models.Warehouse}), + url(r'^container-add-treatment/(?P<pk>[0-9-]+)/$', check_rights(['change_find', 'change_own_find'])( views.container_treatment_add), @@ -91,4 +95,8 @@ urlpatterns = [ name='container_deletion'), url(r'container-modify/(?P<pk>.+)/$', views.container_modify, name='container_modify'), + + url(r'^container-qa-lock/(?P<pks>[0-9-]+)?/$', + views.QAContainerLockView.as_view(), name='container-qa-lock', + kwargs={"model": models.Container}), ] diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index ecbcc3175..67701f70b 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -34,6 +34,7 @@ from archaeological_warehouse.forms import WarehouseForm, ContainerForm, \ ContainerDeletionForm, ContainerSelect, WarehouseSelect from ishtar_common.forms import FinalForm +from ishtar_common.views import QABaseLockView from ishtar_common.views_item import get_item, show_item, new_item from archaeological_finds.views import treatment_add @@ -178,6 +179,12 @@ warehouse_deletion_wizard = WarehouseDeletionWizard.as_view([ label=_(u"Warehouse deletion"), url_name='warehouse_deletion',) + +class QAWarehouseLockView(QABaseLockView): + model = models.Warehouse + base_url = "warehouse-qa-lock" + + container_search_wizard = ContainerSearch.as_view([ ('selec-container_search', MainContainerFormSelection)], label=_(u"Container search"), @@ -252,6 +259,11 @@ warehouse_packaging_wizard = ItemSourceWizard.as_view([ """ +class QAContainerLockView(QABaseLockView): + model = models.Container + base_url = "container-qa-lock" + + def reset_wizards(request): for wizard_class, url_name in ( (PackagingWizard, 'warehouse_packaging'), diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index a69c65f0e..8acd5ffcc 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -698,7 +698,7 @@ def get_form_selection( class_name, label, key, model, base_form, get_url, not_selected_error=_(u"You should select an item."), new=False, new_message=_(u"Add a new item"), get_full_url=None, - gallery=False, map=False): + gallery=False, map=False, base_form_select=None): """ Generate a class selection form class_name -- name of the class @@ -746,7 +746,9 @@ def get_form_selection( return cleaned_data attrs['clean'] = clean attrs['SEARCH_AND_SELECT'] = True - return type(class_name, (forms.Form,), attrs) + if not base_form_select: + base_form_select = forms.Form + return type(class_name, (base_form_select,), attrs) def get_data_from_formset(data): diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 93e1839f0..dd55f95b4 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -1378,6 +1378,27 @@ class QADocumentFormMulti(QAForm): ] +class QALockForm(forms.Form): + action = forms.ChoiceField( + label=_("Action"), choices=(('lock', _("Lock")), + ('unlock', _("Unlock")))) + + def __init__(self, *args, **kwargs): + self.items = kwargs.pop('items') + super(QALockForm, self).__init__(*args, **kwargs) + + def save(self, items, user): + locked = self.cleaned_data["action"] == "lock" + for item in items: + item.locked = locked + if locked: + item.lock_user = user + else: + item.lock_user = None + item.skip_history_when_saving = True + item.save() + + class SourceDeletionForm(FinalForm): confirm_msg = " " confirm_end_msg = _(u"Would you like to delete this documentation?") diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 4ab94aae9..c663eccbc 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -2126,7 +2126,7 @@ class QAItemForm(IshtarMixin, LoginRequiredMixin, FormView): model = None base_url = None form_class = None - page_name = u"" + page_name = "" success_url = "/success/" modal_size = None # large, small or None (medium) @@ -2218,6 +2218,15 @@ class QAItemEditForm(QAItemForm): return HttpResponseRedirect(reverse("success")) +class QABaseLockView(QAItemForm): + form_class = forms.QALockForm + page_name = _("lock/unlock") + + def form_valid(self, form): + form.save(self.items, self.request.user) + return HttpResponseRedirect(reverse("success")) + + class QAPersonForm(QAItemEditForm): model = models.Person form_class = forms.QAPersonFormMulti |