diff options
| -rw-r--r-- | archaeological_context_records/models.py | 10 | ||||
| -rw-r--r-- | archaeological_context_records/urls.py | 7 | ||||
| -rw-r--r-- | archaeological_files/models.py | 35 | ||||
| -rw-r--r-- | archaeological_files/urls.py | 9 | ||||
| -rw-r--r-- | archaeological_finds/models_finds.py | 8 | ||||
| -rw-r--r-- | archaeological_finds/urls.py | 7 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 20 | ||||
| -rw-r--r-- | archaeological_operations/tests.py | 24 | ||||
| -rw-r--r-- | archaeological_operations/urls.py | 13 | ||||
| -rw-r--r-- | archaeological_warehouse/models.py | 19 | ||||
| -rw-r--r-- | archaeological_warehouse/urls.py | 13 | ||||
| -rw-r--r-- | ishtar_common/forms_common.py | 30 | ||||
| -rw-r--r-- | ishtar_common/views.py | 22 | 
13 files changed, 198 insertions, 19 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 1bb09717d..21cc507c1 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -795,6 +795,13 @@ class ContextRecord(              "archaeological_context_records.change_own_contextrecord"          ],      ) +    QA_LINK = QuickAction( +        url="contextrecord-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    )      QA_EDIT = QuickAction(          url="contextrecord-qa-bulk-update",          icon_class="fa fa-pencil", @@ -807,7 +814,6 @@ class ContextRecord(      )      QUICK_ACTIONS = [          QA_EDIT, -        QA_LOCK,          QuickAction(              url="contextrecord-qa-duplicate",              icon_class="fa fa-clone", @@ -818,6 +824,8 @@ class ContextRecord(                  "archaeological_context_records.change_own_contextrecord"              ],          ), +        QA_LOCK, +        QA_LINK,      ]      SERIALIZE_EXCLUDE = MainItem.SERIALIZE_EXCLUDE + ["contextrecord"]      SERIALIZE_PROPERTIES = MainItem.SERIALIZE_PROPERTIES + [ diff --git a/archaeological_context_records/urls.py b/archaeological_context_records/urls.py index 338f5bb2a..c4d6e05bc 100644 --- a/archaeological_context_records/urls.py +++ b/archaeological_context_records/urls.py @@ -21,6 +21,7 @@ from django.conf.urls import url  from django.urls import path  from ishtar_common.utils import check_permissions +from ishtar_common.views import QALinkView  from archaeological_context_records import models, views, views_api  # be careful: each check_permissions must be relevant with ishtar_menu @@ -177,6 +178,12 @@ urlpatterns = [          kwargs={"model": models.ContextRecord},      ),      url( +        r"^contextrecord-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="contextrecord-qa-link", +        kwargs={"model": models.ContextRecord, "url": "contextrecord-qa-link"}, +    ), +    url(          r"^contextrecord-qa-duplicate/(?P<pks>[0-9-]+)?/$",          check_permissions(["archaeological_context_records.change_contextrecord",                             "archaeological_context_records.change_own_contextrecord"])( diff --git a/archaeological_files/models.py b/archaeological_files/models.py index b3815c95d..04481889f 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -45,26 +45,27 @@ from ishtar_common.utils import (  )  from ishtar_common.models import ( +    BaseHistorizedItem, +    CompleteIdentifierItem, +    DashboardFormItem,      Department, +    Document, +    DocumentItem,      GeneralType,      GlobalVar, -    BaseHistorizedItem, -    Imported, -    OwnPerms, -    Person, -    Organization, -    Town, -    DashboardFormItem,      HistoricalRecords, -    ValueGetter, +    HistoryModel, +    Imported,      MainItem,      OperationType, +    Organization, +    OwnPerms, +    Person,      post_save_cache, -    Document, -    HistoryModel, +    QuickAction,      SearchVectorConfig, -    DocumentItem, -    CompleteIdentifierItem, +    Town, +    ValueGetter,  )  from archaeological_operations.models import ( @@ -619,6 +620,16 @@ class File(      HISTORICAL_M2M = ["towns", "departments"]      SERIALIZE_PROPERTIES = ["external_id"] +    QA_LINK = QuickAction( +        url="file-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    ) +    QUICK_ACTIONS = [ +        QA_LINK +    ]      # fields      year = models.IntegerField(_("Year"), default=get_current_year) diff --git a/archaeological_files/urls.py b/archaeological_files/urls.py index 4b50047a6..4c278e0be 100644 --- a/archaeological_files/urls.py +++ b/archaeological_files/urls.py @@ -21,7 +21,8 @@ from django.conf.urls import url  from django.urls import path  from ishtar_common.utils import check_permissions -from archaeological_files import views, views_api +from ishtar_common.views import QALinkView +from archaeological_files import views, views_api, models  from archaeological_operations.views import administrativeactfile_document  # be carreful: each check_permissions must be relevant with ishtar_menu @@ -29,6 +30,12 @@ from archaeological_operations.views import administrativeactfile_document  # forms:  urlpatterns = [      url( +        r"^file-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="file-qa-link", +        kwargs={"model": models.File, "url": "file-qa-link"}, +    ), +    url(          r"file_administrativeactfile_search/(?P<step>.+)?$",          check_permissions(["archaeological_operations.change_administrativeact"])(              views.file_administrativeactfile_search_wizard diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index ece7d08b8..e224dc48c 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1867,6 +1867,13 @@ class Find(          rights=["archaeological_finds.change_find",                  "archaeological_finds.change_own_find"],      ) +    QA_LINK = QuickAction( +        url="find-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    )      QA_LOCK = QuickAction(          url="find-qa-lock",          icon_class="fa fa-lock", @@ -1921,6 +1928,7 @@ class Find(              is_popup=False,          ),          QA_LOCK, +        QA_LINK      ]      UP_MODEL_QUERY = {          "operation": ( diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index ba10750d2..c7d8356ce 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -22,6 +22,7 @@ from django.urls import path  from ishtar_common.utils import check_permissions, get_urls_for_model +from ishtar_common.views import QALinkView  from archaeological_finds import views  from archaeological_finds import views_api  from archaeological_operations.views import administrativeactfile_document @@ -275,6 +276,12 @@ urlpatterns = [          kwargs={"model": models.Find},      ),      url( +        r"^find-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="find-qa-link", +        kwargs={"model": models.Find, "url": "find-qa-link"}, +    ), +    url(          r"^treatment_creation/(?P<step>.+)?$",          check_permissions(              ["archaeological_finds.change_find", diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 9e43f264b..debc26d8b 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -584,6 +584,13 @@ class ArchaeologicalSite(              "archaeological_operations.change_own_archaeologicalsite"          ],      ) +    QA_LINK = QuickAction( +        url="site-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    )      QA_EDIT = QuickAction(          url="site-qa-bulk-update",          icon_class="fa fa-pencil", @@ -596,7 +603,6 @@ class ArchaeologicalSite(      )      QUICK_ACTIONS = [          QA_EDIT, -        QA_LOCK,          QuickAction(              url="site-add-operation",              icon_class="fa fa-plus", @@ -615,6 +621,8 @@ class ArchaeologicalSite(                  "archaeological_operations.change_own_archaeologicalsite"              ],          ), +        QA_LOCK, +        QA_LINK      ]      objects = SiteManager() @@ -1478,9 +1486,15 @@ class Operation(              "archaeological_operations.change_own_operation"          ],      ) +    QA_LINK = QuickAction( +        url="operation-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    )      QUICK_ACTIONS = [          QA_EDIT, -        QA_LOCK,          QuickAction(              url="operation-qa-duplicate",              icon_class="fa fa-clone", @@ -1491,6 +1505,8 @@ class Operation(                  "archaeological_operations.change_own_operation"              ],          ), +        QA_LOCK, +        QA_LINK,      ]      UP_MODEL_QUERY = { diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 18d927d06..41d4a8611 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -4784,6 +4784,30 @@ class OperationQATest(OperationInitTest, TestCase):              Permission.objects.get(codename="change_operation")          ) +    def test_link(self): +        c = Client() +        op0, op1 = self.operations[0], self.operations[1] +        pks = "{}-{}".format(op0.pk, op1.pk) +        url = reverse("operation-qa-link", args=[pks]) + +        response = c.get(url) +        self.assertEqual(response.status_code, 404) + +        c.login(username=self.username, password=self.password) +        response = c.get(reverse("operation-qa-link", args=[pks])) + +        self.assertEqual(response.status_code, 200) +        q_link = models.Operation.objects.filter(ishtar_users__pk__isnull=False) +        self.assertEqual(q_link.count(), 0) + +        response = c.post(url, {"action": "link", "account": self.user.pk}) +        self.assertRedirects(response, "/success/") +        self.assertEqual(q_link.count(), 2) + +        response = c.post(url, {"action": "unlink", "account": self.user.pk}) +        self.assertRedirects(response, "/success/") +        self.assertEqual(q_link.count(), 0) +      def test_lock(self):          c = Client()          op0, op1 = self.operations[0], self.operations[1] diff --git a/archaeological_operations/urls.py b/archaeological_operations/urls.py index ba96c64b2..29b68a349 100644 --- a/archaeological_operations/urls.py +++ b/archaeological_operations/urls.py @@ -21,6 +21,7 @@ from django.conf.urls import url  from django.urls import path, register_converter  from ishtar_common import urls_converters +from ishtar_common.views import QALinkView  from ishtar_common.utils import check_permissions  from archaeological_operations import views  from archaeological_operations import views_api @@ -394,6 +395,12 @@ urlpatterns = [          kwargs={"model": models.Operation},      ),      url( +        r"^operation-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="operation-qa-link", +        kwargs={"model": models.Operation, "url": "operation-qa-link"}, +    ), +    url(          r"^site-qa-duplicate/(?P<pks>[0-9-]+)?/$",          check_permissions(              ["archaeological_operations.change_archaeologicalsite", @@ -408,6 +415,12 @@ urlpatterns = [          kwargs={"model": models.ArchaeologicalSite},      ),      url( +        r"^site-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="site-qa-link", +        kwargs={"model": models.ArchaeologicalSite, "url": "site-qa-link"}, +    ), +    url(          r"^site-qa-bulk-update/(?P<pks>[0-9-]+)?/$",          check_permissions(              ["archaeological_operations.change_archaeologicalsite", diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 5a854c079..099d6a641 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -394,9 +394,17 @@ class Warehouse(              "archaeological_warehouse.change_own_warehouse"          ],      ) +    QA_LINK = QuickAction( +        url="warehouse-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    )      QUICK_ACTIONS = [ -        QA_LOCK,          QA_EDIT, +        QA_LOCK, +        QA_LINK      ]      objects = UUIDModelManager() @@ -1137,7 +1145,14 @@ class Container(              "archaeological_warehouse.change_own_container"          ],      ) -    QUICK_ACTIONS = [QA_EDIT, QA_MOVE, QA_LOCK] +    QA_LINK = QuickAction( +        url="container-qa-link", +        icon_class="fa fa-link", +        text=_("Link to account"), +        target="many", +        rights=["ishtaradmin"], +    ) +    QUICK_ACTIONS = [QA_EDIT, QA_MOVE, QA_LOCK, QA_LINK]      BASE_QUERY_LOCATION = "container_tree_child__container_parent"      SERIALIZE_CALL = { diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py index 669732a57..78bc5945c 100644 --- a/archaeological_warehouse/urls.py +++ b/archaeological_warehouse/urls.py @@ -21,6 +21,7 @@ from django.conf.urls import url  from django.urls import path  from ishtar_common.utils import check_permissions +from ishtar_common.views import QALinkView  from archaeological_warehouse import models, views, views_api @@ -150,6 +151,12 @@ urlpatterns = [          kwargs={"model": models.Warehouse},      ),      url( +        r"^warehouse-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="warehouse-qa-link", +        kwargs={"model": models.Warehouse, "url": "warehouse-qa-link"}, +    ), +    url(          r"^warehouse-qa-bulk-update/(?P<pks>[0-9-]+)?/$",          check_permissions([              "archaeological_warehouse.change_warehouse", @@ -248,6 +255,12 @@ urlpatterns = [          kwargs={"model": models.Container},      ),      url( +        r"^container-qa-link/(?P<pks>[0-9-]+)?/$", +        QALinkView.as_view(), +        name="container-qa-link", +        kwargs={"model": models.Container, "url": "container-qa-link"}, +    ), +    url(          r"container-merge/(?:(?P<page>\d+)/)?$",          views.container_merge,          name="container_merge", diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 734707419..e7e6a334d 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -2833,6 +2833,36 @@ class QALockForm(forms.Form):              item.save() +class QALinkForm(forms.Form): +    action = forms.ChoiceField( +        label=_("Action"), +        choices=(("link", _("Link items")), ("unlink", _("Unlink items"))) +    ) +    account = forms.IntegerField( +        widget=widgets.JQueryAutoComplete( +            reverse_lazy( +                'autocomplete-user', +            ), +            associated_model=User), +        label=_("User")) + +    def __init__(self, *args, **kwargs): +        self.items = kwargs.pop("items") +        super().__init__(*args, **kwargs) + +    def save(self, items, user): +        try: +            ishtar_user = models.IshtarUser.objects.get(pk=self.cleaned_data["account"]) +        except models.IshtarUser.DoesNotExist: +            return +        if self.cleaned_data["action"] == "link": +            for item in items: +                item.ishtar_users.add(ishtar_user) +        else: +            for item in items: +                item.ishtar_users.remove(ishtar_user) + +  class SourceDeletionForm(FinalForm):      confirm_msg = " "      confirm_end_msg = _("Would you like to delete this documentation?") diff --git a/ishtar_common/views.py b/ishtar_common/views.py index f01e848a0..03b029fe2 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -3121,7 +3121,10 @@ class QAItemForm(IshtarMixin, LoginRequiredMixin, FormView):      def pre_dispatch(self, request, *args, **kwargs):          if not self.model: -            raise NotImplementedError("No attribute model defined.") +            if "model" in kwargs: +                self.model = kwargs["model"] +            else: +                raise NotImplementedError("No attribute model defined.")          pks = [int(pk) for pk in kwargs.get("pks").split("-")]          self.items = list(self.model.objects.filter(pk__in=pks))          if not self.items: @@ -3252,6 +3255,23 @@ class QABaseLockView(QAItemForm):          return HttpResponseRedirect(reverse("success")) +class QALinkView(QAItemForm): +    form_class = forms.QALinkForm +    page_name = _("Link items") +    icon = "fa fa-link" + +    def pre_dispatch(self, request, *args, **kwargs): +        self.base_url = kwargs["url"] +        super().pre_dispatch(request, *args, **kwargs) +        if not request.user.ishtaruser.is_ishtaradmin: +            url = reverse("qa-not-available") +            return HttpResponseRedirect(url) + +    def form_valid(self, form): +        form.save(self.items, self.request.user) +        return HttpResponseRedirect(reverse("success")) + +  class QAOrganizationForm(QAItemEditForm):      model = models.Organization      form_class = forms.QAOrganizationFormMulti  | 
