summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit8f18e7aa3ef8750faaf8c4cd136827555fdf66e4 (patch)
tree45f1d910b67a30e44015735581ec9cdc6db51cdf
parent3d630a998043a9a6a9d61d42f3394b121f045431 (diff)
downloadIshtar-8f18e7aa3ef8750faaf8c4cd136827555fdf66e4.tar.bz2
Ishtar-8f18e7aa3ef8750faaf8c4cd136827555fdf66e4.zip
QA: lock/unlock (sites, operations, context records, finds, containers, warehouses)
-rw-r--r--archaeological_context_records/models.py14
-rw-r--r--archaeological_context_records/urls.py4
-rw-r--r--archaeological_context_records/views.py9
-rw-r--r--archaeological_finds/models_finds.py6
-rw-r--r--archaeological_finds/urls.py4
-rw-r--r--archaeological_finds/views.py7
-rw-r--r--archaeological_operations/forms.py2
-rw-r--r--archaeological_operations/models.py22
-rw-r--r--archaeological_operations/urls.py8
-rw-r--r--archaeological_operations/views.py12
-rw-r--r--archaeological_warehouse/forms.py12
-rw-r--r--archaeological_warehouse/models.py20
-rw-r--r--archaeological_warehouse/urls.py8
-rw-r--r--archaeological_warehouse/views.py12
-rw-r--r--ishtar_common/forms.py6
-rw-r--r--ishtar_common/forms_common.py21
-rw-r--r--ishtar_common/views.py11
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