#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2010-2018 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. from collections import OrderedDict import json from rest_framework import authentication, permissions from rest_framework.views import APIView from rest_framework.response import Response from django.conf import settings from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.db.models import Q from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.shortcuts import redirect from ishtar_common.utils import ugettext_lazy as _ from django.views.generic import TemplateView from django.views.generic.edit import CreateView, FormView from ishtar_common.serializers import PublicSerializer from ishtar_common.models import IshtarUser, get_current_profile from archaeological_operations.models import AdministrativeAct from archaeological_finds import models from ishtar_common.forms import FinalForm from archaeological_context_records.forms import ( RecordFormSelection as RecordFormSelectionTable, ) from archaeological_operations.forms import FinalAdministrativeActDeleteForm from archaeological_finds import forms from ishtar_common.views import ( get_autocomplete_generic, IshtarMixin, LoginRequiredMixin, QAItemEditForm, QAItemForm, QABaseLockView, wizard_is_available, ) from ishtar_common.views_item import ( display_item, get_item, show_item, revert_item, get_autocomplete_item, get_autocomplete_queries, ) from archaeological_operations.wizards import AdministrativeActDeletionWizard from archaeological_finds import wizards get_find = get_item(models.Find, "get_find", "find", search_form=forms.FindSelect) def get_table_cols_for_ope(): tb_key = (models.Find.SLUG, "TABLE_COLS_FOR_OPE") if tb_key not in settings.TABLE_COLS: return models.Find.TABLE_COLS_FOR_OPE return settings.TABLE_COLS[tb_key] def get_table_cols_for_cr(): tb_key = (models.Find.SLUG, "TABLE_COLS_FOR_CR") if tb_key not in settings.TABLE_COLS: return models.Find.TABLE_COLS_FOR_CR return settings.TABLE_COLS[tb_key] def get_table_cols_for_container(): table_cols = models.Find.TABLE_COLS tb_key = ("find", "TABLE_COLS") if tb_key in settings.TABLE_COLS: table_cols = settings.TABLE_COLS[tb_key] return ["find__" + tc for tc in table_cols] get_find_for_ope = get_item( models.Find, "get_find", "find", own_table_cols=get_table_cols_for_ope() ) get_find_for_cr = get_item( models.Find, "get_find", "find", own_table_cols=get_table_cols_for_cr() ) get_find_for_treatment = get_item( models.Find, "get_find", "find", own_table_cols=get_table_cols_for_ope(), base_request={}, ) get_find_inside_container = get_item( models.FindInsideContainer, "get_find_inside_container", "find", extra_request_keys=models.FindInsideContainer.EXTRA_REQUEST_KEYS, own_table_cols=get_table_cols_for_container(), ) autocomplete_find = get_autocomplete_item(model=models.Find) show_treatment = show_item(models.Treatment, "treatment") revert_treatment = revert_item(models.Treatment) get_treatment = get_item( models.Treatment, "get_treatment", "treatment", search_form=forms.TreatmentSelect ) display_treatment = display_item(models.Treatment) autocomplete_treatment = get_autocomplete_item(model=models.Treatment) get_administrativeacttreatment = get_item( AdministrativeAct, "get_administrativeacttreatment", "administrativeacttreatment", base_request={"treatment__pk__isnull": False}, ) show_treatmentfile = show_item(models.TreatmentFile, "treatmentfile") revert_treatmentfile = revert_item(models.TreatmentFile) get_treatmentfile = get_item( models.TreatmentFile, "get_treatmentfile", "treatmentfile", search_form=forms.TreatmentFileSelect, ) get_administrativeacttreatmentfile = get_item( AdministrativeAct, "get_administrativeacttreatmentfile", "administrativeacttreatmentfile", base_request={"treatment_file__pk__isnull": False}, ) def autocomplete_treatmentfile(request): if ( not request.user.has_perm("ishtar_common.view_treatment", models.Treatment) and not request.user.has_perm( "ishtar_common.view_own_treatment", models.Treatment ) and not request.user.ishtaruser.has_right( "treatmentfile_search", session=request.session ) ): return HttpResponse(content_type="text/plain") if not request.GET.get("term"): return HttpResponse(content_type="text/plain") q = request.GET.get("term") query = Q() for q1 in q.split(" "): for q in q1.split(" "): extra = ( Q(internal_reference__icontains=q) | Q(external_id__icontains=q) | Q(name__icontains=q) ) try: int(q) extra = extra | Q(year=q) | Q(index=q) except ValueError: pass query = query & extra limit = 20 files = models.TreatmentFile.objects.filter(query)[:limit] data = json.dumps([{"id": file.pk, "value": str(file)} for file in files]) return HttpResponse(data, content_type="text/plain") def show_basefind(request, pk, **dct): q = models.Find.objects.filter(base_finds__pk=pk, downstream_treatment__isnull=True) if not q.count(): return Http404() find_pk = q.values("pk").order_by("-pk")[0]["pk"] return show_item(models.Find, "find")(request, find_pk, **dct) def show_find_extra(request, find): if not request.user or not request.user.ishtaruser: return {} user = request.user.ishtaruser q = ( models.FindBasket.objects.filter(items__pk=find.pk) .filter( Q(user=user) | Q(shared_with__pk=user.pk) | Q(shared_write_with__pk=user.pk) ) .distinct() ) return {"baskets": [(basket.pk, basket.full_label) for basket in q.all()]} show_find = show_item(models.Find, "find", extra_dct=show_find_extra) display_find = display_item(models.Find) revert_find = revert_item(models.Find) show_findbasket = show_item( models.FindBasket, "findbasket", model_for_perms=models.Find ) display_findbasket = display_item(models.FindBasket, show_url="show-find/basket-") def autocomplete_findbasket(request, current_right=None): if not request.GET.get("term"): return HttpResponse(content_type="text/plain") limit = 20 result = OrderedDict() for query in get_autocomplete_queries(request, ["label"]): query = query & models.FindBasket.get_query_owns(request.user.ishtaruser) objects = ( models.FindBasket.objects.filter(query).distinct().order_by("label")[:limit] ) for obj in objects: if obj.id not in list(result.keys()): result[obj.id] = obj.label limit -= 1 if not limit: break if not limit: break data = json.dumps([{"id": obj[0], "value": obj[1]} for obj in list(result.items())]) return HttpResponse(data, content_type="text/plain") def autocomplete_findbasket_write(request, current_right=None): if not request.GET.get("term"): return HttpResponse(content_type="text/plain") limit = 20 result = OrderedDict() for query in get_autocomplete_queries(request, ["label"]): query = query & models.FindBasket.get_write_query_owns(request.user.ishtaruser) objects = ( models.FindBasket.objects.filter(query).distinct().order_by("label")[:limit] ) for obj in objects: if obj.id not in list(result.keys()): result[obj.id] = obj.label limit -= 1 if not limit: break if not limit: break data = json.dumps([{"id": obj[0], "value": obj[1]} for obj in list(result.items())]) return HttpResponse(data, content_type="text/plain") get_find_basket = get_item( models.FindBasket, "get_findbasket", "findbasket", model_for_perms=models.Find ) get_findbasket = get_find_basket get_find_basket_for_write = get_item( models.FindBasket, "get_findbasket", "findbasket", model_for_perms=models.Find, alt_query_own="get_write_query_owns", ) basket_search_wizard = wizards.FindBasketSearch.as_view( [("selec-find_basket_search", forms.FindBasketFormSelection)], label=_("Basket search"), url_name="find_basket_search", ) basket_modify_wizard = wizards.FindBasketEditWizard.as_view( [ ("selec-find_basket_modification", forms.FindBasketForWriteFormSelection), ("basket-find_basket_modification", forms.FindBasketForm), ("final-find_basket_modification", FinalForm), ], label=_("Basket modify"), url_name="find_basket_modification", ) def find_basket_modify(request, pk): if not wizard_is_available(basket_modify_wizard, request, models.FindBasket, pk): return HttpResponseRedirect("/") key = "selec-find_basket_modification" wizards.FindBasketEditWizard.session_set_value(request, key, "pk", pk, reset=True) return redirect( reverse( "find_basket_modification", kwargs={"step": "basket-find_basket_modification"}, ) ) findbasket_deletion_steps = [ ("selec-find_basket_deletion", forms.FindBasketForWriteFormSelection), ("final-find_basket_deletion", FinalForm), ] basket_delete_wizard = wizards.FindBasketDeletionWizard.as_view( findbasket_deletion_steps, label=_("Basket deletion"), url_name="find_basket_deletion", ) def check_preservation_module(self): return get_current_profile().preservation def check_warehouse_module(self): return get_current_profile().warehouse def check_not_warehouse_module(self): return not check_warehouse_module(self) find_creation_steps = [ ("selecrecord-find_creation", RecordFormSelectionTable), ("find-find_creation", forms.FindForm), ("preservation-find_creation", forms.PreservationForm), ("dating-find_creation", forms.DatingFormSet), ("final-find_creation", FinalForm), ] find_creation_condition_dict = { "preservation-find_creation": check_preservation_module, } find_creation_wizard = wizards.FindWizard.as_view( find_creation_steps, label=_("New find"), condition_dict=find_creation_condition_dict, url_name="find_creation", ) find_search_condition_dict = { "general-find_search": check_not_warehouse_module, "generalwarehouse-find_search": check_warehouse_module, } find_search_wizard = wizards.FindSearch.as_view( [ ("general-find_search", forms.FindFormSelection), ("generalwarehouse-find_search", forms.FindFormSelectionWarehouseModule), ], label=_("Find search"), url_name="find_search", condition_dict=find_search_condition_dict, ) def has_many_base_find(wizard): find = wizard.get_current_object() if not find: return False return find.base_finds.count() > 1 def has_only_one_base_find(wizard): return not has_many_base_find(wizard) find_modification_condition_dict = { "selec-find_modification": check_not_warehouse_module, "selecw-find_modification": check_warehouse_module, "preservation-find_modification": check_preservation_module, "selecrecord-find_modification": has_only_one_base_find, "find-find_modification": has_only_one_base_find, "simplefind-find_modification": has_many_base_find, } find_modification_steps = [ ("selec-find_modification", forms.FindFormSelection), ("selecw-find_modification", forms.FindFormSelectionWarehouseModule), ("selecrecord-find_modification", forms.RecordFormSelection), ("find-find_modification", forms.FindForm), ("simplefind-find_modification", forms.SimpleFindForm), ("preservation-find_modification", forms.PreservationForm), ("dating-find_modification", forms.DatingFormSet), ("final-find_modification", FinalForm), ] find_modification_wizard = wizards.FindModificationWizard.as_view( find_modification_steps, condition_dict=find_modification_condition_dict, label=_("Find modification"), url_name="find_modification", ) def find_modify(request, pk): find = wizard_is_available(find_modification_wizard, request, models.Find, pk) if not find: return HttpResponseRedirect("/") find_modification_wizard(request) key = "selec-find_modification" if get_current_profile().warehouse: key = "selecw-find_modification" wizards.FindModificationWizard.session_set_value(request, key, "pk", pk, reset=True) step = "find-find_modification" if find.base_finds.count() > 1: step = "simplefind-find_modification" return redirect(reverse("find_modification", kwargs={"step": step})) find_deletion_condition_dict = { "selec-find_deletion": check_not_warehouse_module, "selecw-find_deletion": check_warehouse_module, } find_deletion_steps = [ ("selec-find_deletion", forms.FindFormMultiSelection), ("selecw-find_deletion", forms.FindFormMultiSelectionWarehouseModule), ("final-find_deletion", forms.FindDeletionForm), ] find_deletion_wizard = wizards.FindDeletionWizard.as_view( find_deletion_steps, condition_dict=find_deletion_condition_dict, label=_("Find deletion"), url_name="find_deletion", ) def find_delete(request, pk): find = wizard_is_available(find_deletion_wizard, request, models.Find, pk) if not find: return HttpResponseRedirect("/") key = "selec-find_deletion" if get_current_profile().warehouse: key = "selecw-find_deletion" wizards.FindDeletionWizard.session_set_value(request, key, "pks", pk, reset=True) step = "final-find_deletion" return redirect(reverse("find_deletion", kwargs={"step": step})) autocomplete_objecttype = get_autocomplete_generic(models.ObjectType) autocomplete_materialtype = get_autocomplete_generic(models.MaterialType) autocomplete_treatmenttype = get_autocomplete_generic(models.TreatmentType) autocomplete_integritytype = get_autocomplete_generic(models.IntegrityType) autocomplete_functionalarea = get_autocomplete_generic(models.FunctionalArea) class NewFindBasketView(IshtarMixin, LoginRequiredMixin, CreateView): template_name = "ishtar/form.html" model = models.FindBasket form_class = forms.NewFindBasketForm page_name = _("New basket") def get_form_kwargs(self): kwargs = super(NewFindBasketView, self).get_form_kwargs() kwargs["user"] = IshtarUser.objects.get(pk=self.request.user.pk) return kwargs def get_success_url(self): return reverse("select_itemsinbasket", kwargs={"pk": self.object.pk}) def form_valid(self, form): self.object = form.save() return HttpResponseRedirect(self.get_success_url()) class OwnBasket(object): def get_basket(self, user, pk): try: return ( models.FindBasket.objects.filter( Q(user=user) | Q(shared_with=user) | Q(shared_write_with=user) ) .distinct() .get(pk=pk) ) except models.FindBasket.DoesNotExist: raise PermissionDenied class SelectBasketForManagement(IshtarMixin, LoginRequiredMixin, FormView): template_name = "ishtar/form.html" form_class = forms.SelectFindBasketWriteForm page_name = _("Manage items in basket") def get_form_kwargs(self): kwargs = super(SelectBasketForManagement, self).get_form_kwargs() kwargs["user"] = IshtarUser.objects.get(pk=self.request.user.pk) if "pk" in self.kwargs: kwargs["initial"].update({"basket": self.kwargs["pk"]}) return kwargs 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"])) class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin, TemplateView): template_name = "ishtar/manage_basket.html" page_name = _("Manage basket") def get_context_data(self, *args, **kwargs): context = super(SelectItemsInBasket, self).get_context_data(*args, **kwargs) self.user = IshtarUser.objects.get(pk=self.request.user.pk) self.basket = self.get_basket(user=self.user, pk=self.kwargs["pk"]) context["basket"] = self.basket if get_current_profile().warehouse: context["form"] = forms.MultipleFindFormSelectionWarehouseModule() else: context["form"] = forms.MultipleFindFormSelection() context["add_url"] = reverse("add_iteminbasket") context["list_url"] = reverse( "list_iteminbasket", kwargs={"pk": self.basket.pk} ) return context def form_valid(self, form): return HttpResponseRedirect(self.get_success_url()) class FindBasketAddItemView(IshtarMixin, LoginRequiredMixin, FormView): template_name = "ishtar/simple_form.html" form_class = forms.FindBasketAddItemForm def get_success_url(self, basket): return reverse("list_iteminbasket", kwargs={"pk": basket.pk}) def form_valid(self, form): user = IshtarUser.objects.get(pk=self.request.user.pk) # rights are checked on the form basket = form.save(user) return HttpResponseRedirect(self.get_success_url(basket)) class FindBasketListView(OwnBasket, IshtarMixin, LoginRequiredMixin, TemplateView): template_name = "ishtar/basket_list.html" def get_context_data(self, *args, **kwargs): context = super(FindBasketListView, self).get_context_data(*args, **kwargs) self.user = IshtarUser.objects.get(pk=self.request.user.pk) self.basket = self.get_basket(user=self.user, pk=self.kwargs["pk"]) context["basket"] = self.basket context["item_url"] = "/".join( reverse(models.Find.SHOW_URL, args=[1]).split("/")[:-1] ) context["delete_url"] = "/".join( reverse("delete_iteminbasket", args=[1, 1]).split("/")[:-3] ) return context class FindBasketDeleteItemView( OwnBasket, IshtarMixin, LoginRequiredMixin, TemplateView ): template_name = "ishtar/simple_form.html" def get_success_url(self, basket): return reverse("list_iteminbasket", kwargs={"pk": basket.pk}) def get(self, *args, **kwargs): user = self.request.user ishtaruser = IshtarUser.objects.get(pk=self.request.user.pk) try: find = models.Find.objects.get(pk=self.kwargs["find_pk"]) except models.Find.DoesNotExist: raise PermissionDenied basket = self.get_basket(user=ishtaruser, pk=self.kwargs["basket"]) if ( not user.is_superuser and not ishtaruser.has_right("view_find") and not (ishtaruser.has_right("view_own_find") and find.is_own(user)) ): raise PermissionDenied basket.items.remove(find) return HttpResponseRedirect(self.get_success_url(basket)) get_upstreamtreatment = get_item( models.FindUpstreamTreatments, "get_upstreamtreatment", "uptreatment" ) get_downstreamtreatment = get_item( models.FindDownstreamTreatments, "get_downstreamtreatment", "downtreatment" ) treatment_wizard_steps = [ ("selecfind-treatment_creation", forms.UpstreamFindFormSelection), ("file-treatment_creation", forms.TreatmentFormFileChoice), ("basetreatment-treatment_creation", forms.BaseTreatmentForm), ("final-treatment_creation", FinalForm), ] treatment_search_wizard = wizards.TreatmentSearch.as_view( [("general-treatment_search", forms.TreatmentFormSelection)], label=_("Treatment search"), url_name="treatment_search", ) treatment_creation_wizard = wizards.TreatmentWizard.as_view( treatment_wizard_steps, label=_("New treatment"), url_name="treatment_creation", ) treatment_n1_wizard_steps = [ ("selecfind-treatment_creation_n1", forms.UpstreamFindFormSelection), ("file-treatment_creation_n1", forms.TreatmentFormFileChoice), ("basetreatment-treatment_creation_n1", forms.N1TreatmentForm), ("resultingfind-treatment_creation_n1", forms.ResultingFindForm), ("final-treatment_creation_n1", FinalForm), ] treatment_creation_n1_wizard = wizards.TreatmentN1Wizard.as_view( treatment_n1_wizard_steps, label=_("New treatment"), url_name="treatment_creation_n1", ) treatment_1n_wizard_steps = [ ("selecfind-treatment_creation_1n", forms.SingleUpstreamFindFormSelection), ("file-treatment_creation_1n", forms.TreatmentFormFileChoice), ("basetreatment-treatment_creation_1n", forms.OneNTreatmentForm), ("resultingfinds-treatment_creation_1n", forms.ResultingFindsForm), ("final-treatment_creation_1n", FinalForm), ] treatment_creation_1n_wizard = wizards.Treatment1NWizard.as_view( treatment_1n_wizard_steps, label=_("New treatment"), url_name="treatment_creation_1n", ) treatment_modification_wizard = wizards.TreatmentModificationWizard.as_view( [ ("selec-treatment_modification", forms.TreatmentFormSelection), ("file-treatment_modification", forms.TreatmentFormFileChoice), ("basetreatment-treatment_modification", forms.TreatmentModifyForm), ("final-treatment_modification", FinalForm), ], label=_("Treatment modification"), url_name="treatment_modification", ) def treatment_modify(request, pk): if not wizard_is_available( treatment_modification_wizard, request, models.Treatment, pk ): return HttpResponseRedirect("/") wizards.TreatmentModificationWizard.session_set_value( request, "selec-treatment_modification", "pk", pk, reset=True ) return redirect( reverse( "treatment_modification", kwargs={"step": "file-treatment_modification"} ) ) def treatment_add(request, pks, treatment_file=None): treatment_creation_wizard(request) wizards.TreatmentWizard.session_set_value( request, "selecfind-treatment_creation", "resulting_pk", pks, reset=True ) if treatment_file: wizards.TreatmentWizard.session_set_value( request, "file-treatment_creation", "file", treatment_file.pk ) else: wizards.TreatmentWizard.session_set_value( request, "file-treatment_creation", "file", "" ) if treatment_file: in_charge = treatment_file.in_charge if not in_charge: in_charge = request.user.ishtaruser.person dct = { "treatment_type": treatment_file.type.treatment_type.pk if treatment_file.type and treatment_file.type.treatment_type else "", "year": treatment_file.year, "person": in_charge.pk, } locas = list( { str(f.container.location.pk) for f in treatment_file.associated_basket.items.all() if f.container and f.container.location } ) if len(locas) == 1: # one and only one location for all finds dct["location"] = locas[0] for k in dct: wizards.TreatmentWizard.session_set_value( request, "basetreatment-treatment_creation", k, dct[k] ) return redirect( reverse( "treatment_creation", kwargs={"step": "basetreatment-treatment_creation"} ) ) def divide_treatment_add(request, pks, treatment_file=None): treatment_creation_1n_wizard(request) wizards.Treatment1NWizard.session_set_value( request, "selecfind-treatment_creation_1n", "resulting_pk", pks, reset=True ) if treatment_file: wizards.Treatment1NWizard.session_set_value( request, "file-treatment_creation_1n", "file", treatment_file.pk ) else: wizards.Treatment1NWizard.session_set_value( request, "file-treatment_creation_1n", "file", "" ) if treatment_file: in_charge = treatment_file.in_charge if not in_charge: in_charge = request.user.ishtaruser.person dct = { "treatment_type": treatment_file.type.treatment_type.pk if treatment_file.type and treatment_file.type.treatment_type else "", "year": treatment_file.year, "person": in_charge.pk, } locas = list( { str(f.container.location.pk) for f in treatment_file.associated_basket.items.all() if f.container and f.container.location } ) if len(locas) == 1: # one and only one location for all finds dct["location"] = locas[0] for k in dct: wizards.Treatment1NWizard.session_set_value( request, "basetreatment-treatment_creation_1n", k, dct[k] ) return redirect( reverse( "treatment_creation_1n", kwargs={"step": "basetreatment-treatment_creation_1n"}, ) ) def find_treatment_add(request, pk, current_right=None): if not models.Find.objects.filter(pk=pk).count(): raise Http404() return treatment_add(request, str(pk)) def find_divide_treatment_add(request, pk, current_right=None): if not models.Find.objects.filter(pk=pk).count(): raise Http404() return divide_treatment_add(request, str(pk)) def findbasket_treatment_add(request, pk, current_right=None): try: basket = models.FindBasket.objects.get(pk=pk) except models.FindBasket.DoesNotExist: raise Http404() return treatment_add(request, ",".join(str(f.pk) for f in basket.items.all())) def findbasket_treatmentfile_add(request, pk, current_right=None): try: basket = models.FindBasket.objects.get(pk=pk) except models.FindBasket.DoesNotExist: raise Http404() return treatmentfile_add(request, basket_pk=basket.pk) def container_treatment_add(request, pk, current_right=None): try: basket = models.FindBasket.objects.get(pk=pk) except models.FindBasket.DoesNotExist: raise Http404() return treatment_add(request, ",".join(str(f.pk) for f in basket.items.all())) def treatmentfile_treatment_add(request, pk, current_right=None): try: tf = models.TreatmentFile.objects.get(pk=pk) except models.TreatmentFile.DoesNotExist: raise Http404() if not tf.associated_basket: raise Http404() basket = tf.associated_basket return treatment_add( request, ",".join(str(f.pk) for f in basket.items.all()), treatment_file=tf, ) treatment_deletion_wizard = wizards.TreatmentDeletionWizard.as_view( [ ("selec-treatment_deletion", forms.TreatmentFormSelection), ("final-treatment_deletion", forms.TreatmentDeletionForm), ], label=_("Treatment deletion"), url_name="treatment_deletion", ) def treatment_delete(request, pk): if not wizard_is_available( treatment_deletion_wizard, request, models.Treatment, pk ): return HttpResponseRedirect("/") wizards.TreatmentDeletionWizard.session_set_value( request, "selec-treatment_deletion", "pk", pk, reset=True ) return redirect( reverse("treatment_deletion", kwargs={"step": "final-treatment_deletion"}) ) treatment_administrativeact_search_wizard = wizards.SearchWizard.as_view( [ ( "selec-treatment_admacttreatment_search", forms.AdministrativeActTreatmentFormSelection, ) ], label=_("Treatment: search administrative act"), url_name="treatment_admacttreatment_search", ) treatment_administrativeact_wizard = wizards.TreatmentAdministrativeActWizard.as_view( [ ("selec-treatment_admacttreatment", forms.TreatmentFormSelection), ( "administrativeact-treatment_admacttreatment", forms.AdministrativeActTreatmentForm, ), ("final-treatment_admacttreatment", FinalForm), ], label=_("Treatment: new administrative act"), url_name="treatment_admacttreatment", ) treatment_administrativeact_modification_wizard = ( wizards.TreatmentEditAdministrativeActWizard.as_view( [ ( "selec-treatment_admacttreatment_modification", forms.AdministrativeActTreatmentFormSelection, ), ( "administrativeact-treatment_admacttreatment_modification", forms.AdministrativeActTreatmentModifForm, ), ("final-treatment_admacttreatment_modification", FinalForm), ], label=_("Treatment: administrative act modification"), url_name="treatment_admacttreatment_modification", ) ) def treatment_administrativeacttreatment_modify(request, pk): if not wizard_is_available( treatment_administrativeact_modification_wizard, request, AdministrativeAct, pk ): return HttpResponseRedirect("/") wizards.TreatmentEditAdministrativeActWizard.session_set_value( request, "selec-treatment_admacttreatment_modification", "pk", pk, reset=True ) return redirect( reverse( "treatment_admacttreatment_modification", kwargs={"step": "administrativeact-treatment_admacttreatment_modification"}, ) ) treatment_admacttreatment_deletion_wizard = AdministrativeActDeletionWizard.as_view( [ ( "selec-treatment_admacttreatment_deletion", forms.AdministrativeActTreatmentFormSelection, ), ("final-treatment_admacttreatment_deletion", FinalAdministrativeActDeleteForm), ], label=_("Treatment: administrative act deletion"), url_name="treatment_admacttreatment_deletion", ) def treatment_administrativeacttreatment_delete(request, pk): if not wizard_is_available( treatment_admacttreatment_deletion_wizard, request, AdministrativeAct, pk ): return HttpResponseRedirect("/") wizard_url = "treatment_admacttreatment_deletion" AdministrativeActDeletionWizard.session_set_value( request, "selec-" + wizard_url, "pk", pk, reset=True ) return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) def treatment_adminact_add(request, pk, current_right=None): try: models.Treatment.objects.get(pk=pk) except models.Treatment.DoesNotExist: raise Http404() treatment_administrativeact_wizard(request) wizards.TreatmentAdministrativeActWizard.session_set_value( request, "selec-treatment_admacttreatment", "pk", pk, reset=True ) return redirect( reverse( "treatment_admacttreatment", kwargs={"step": "administrativeact-treatment_admacttreatment"}, ) ) # treatment request treatmentfile_search_wizard = wizards.TreatmentFileSearch.as_view( [("general-treatmentfile_search", forms.TreatmentFileFormSelection)], label=_("Treatment request search"), url_name="treatmentfile_search", ) treatmentfile_wizard_steps = [ ("treatmentfile-treatmentfile_creation", forms.TreatmentFileForm), ("final-treatmentfile_creation", FinalForm), ] treatmentfile_creation_wizard = wizards.TreatmentFileWizard.as_view( treatmentfile_wizard_steps, label=_("New treatment request"), url_name="treatmentfile_creation", ) treatmentfile_modification_wizard = wizards.TreatmentFileModificationWizard.as_view( [ ("selec-treatmentfile_modification", forms.TreatmentFileFormSelection), ("treatmentfile-treatmentfile_modification", forms.TreatmentFileModifyForm), ("final-treatmentfile_modification", FinalForm), ], label=_("Treatment request modification"), url_name="treatmentfile_modification", ) def treatmentfile_modify(request, pk): if not wizard_is_available( treatmentfile_modification_wizard, request, models.TreatmentFile, pk ): return HttpResponseRedirect("/") wizards.TreatmentFileModificationWizard.session_set_value( request, "selec-treatmentfile_modification", "pk", pk, reset=True ) return redirect( reverse( "treatmentfile_modification", kwargs={"step": "treatmentfile-treatmentfile_modification"}, ) ) def treatmentfile_add(request, basket_pk=None): treatmentfile_creation_wizard(request) wizards.TreatmentFileWizard.session_set_value( request, "treatmentfile-treatmentfile_creation", "associated_basket", basket_pk, reset=True, ) url = reverse( "treatmentfile_creation", kwargs={"step": "treatmentfile-treatmentfile_creation"}, ) url += "?associated_basket={}".format(basket_pk) return redirect(url) treatmentfile_deletion_wizard = wizards.TreatmentFileDeletionWizard.as_view( [ ("selec-treatmentfile_deletion", forms.TreatmentFileFormSelectionMultiple), ("final-treatmentfile_deletion", forms.TreatmentFileDeletionForm), ], label=_("Treatment request deletion"), url_name="treatmentfile_deletion", ) def treatmentfile_delete(request, pk): if not wizard_is_available( treatmentfile_deletion_wizard, request, models.TreatmentFile, pk ): return HttpResponseRedirect("/") wizard_url = "treatmentfile_deletion" wizards.TreatmentFileDeletionWizard.session_set_value( request, "selec-" + wizard_url, "pks", pk, reset=True ) return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) treatmentfile_admacttreatmentfile_search_wizard = wizards.SearchWizard.as_view( [ ( "selec-treatmentfle_admacttreatmentfle_search", forms.AdministrativeActTreatmentFileFormSelection, ) ], label=_("Treatment request: search administrative act"), url_name="treatmentfle_admacttreatmentfle_search", ) treatmentfile_admacttreatmentfile_wizard = ( wizards.TreatmentFileAdministrativeActWizard.as_view( [ ("selec-treatmentfle_admacttreatmentfle", forms.TreatmentFileFormSelection), ( "admact-treatmentfle_admacttreatmentfle", forms.AdministrativeActTreatmentFileForm, ), ("final-treatmentfle_admacttreatmentfle", FinalForm), ], label=_("Treatment request: new administrative act"), url_name="treatmentfle_admacttreatmentfle", ) ) treatmentfile_admacttreatmentfile_modification_wizard = ( wizards.TreatmentFileEditAdministrativeActWizard.as_view( [ ( "selec-treatmentfle_admacttreatmentfle_modification", forms.AdministrativeActTreatmentFileFormSelection, ), ( "admact-treatmentfle_admacttreatmentfle_modification", forms.AdministrativeActTreatmentFileModifForm, ), ("final-treatmentfle_admacttreatmentfle_modification", FinalForm), ], label=_("Treatment request: administrative act modification"), url_name="treatmentfle_admacttreatmentfle_modification", ) ) def treatmentfile_administrativeacttreatmentfile_modify(request, pk): if not wizard_is_available( treatmentfile_admacttreatmentfile_modification_wizard, request, AdministrativeAct, pk, ): return HttpResponseRedirect("/") wizards.TreatmentFileEditAdministrativeActWizard.session_set_value( request, "selec-treatmentfle_admacttreatmentfle_modification", "pk", pk, reset=True, ) return redirect( reverse( "treatmentfle_admacttreatmentfle_modification", kwargs={"step": "admact-treatmentfle_admacttreatmentfle_modification"}, ) ) def treatmentfile_adminact_add(request, pk, current_right=None): try: models.TreatmentFile.objects.get(pk=pk) except models.TreatmentFile.DoesNotExist: raise Http404() treatmentfile_admacttreatmentfile_wizard(request) wizards.TreatmentFileAdministrativeActWizard.session_set_value( request, "selec-treatmentfle_admacttreatmentfle", "pk", pk, reset=True ) return redirect( reverse( "treatmentfle_admacttreatmentfle", kwargs={"step": "admact-treatmentfle_admacttreatmentfle"}, ) ) treatmentfile_admacttreatmentfile_deletion_wizard = ( AdministrativeActDeletionWizard.as_view( [ ( "selec-treatmentfle_admacttreatmentfle_deletion", forms.AdministrativeActTreatmentFileFormSelection, ), ( "final-treatmentfle_admacttreatmentfle_deletion", FinalAdministrativeActDeleteForm, ), ], label=_("Treatment request: administrative act deletion"), url_name="treatmentfle_admacttreatmentfle_deletion", ) ) def treatmentfile_administrativeacttreatmentfile_delete(request, pk): if not wizard_is_available( treatmentfile_admacttreatmentfile_deletion_wizard, request, AdministrativeAct, pk, ): return HttpResponseRedirect("/") wizard_url = "treatmentfle_admacttreatmentfle_deletion" AdministrativeActDeletionWizard.session_set_value( request, "selec-" + wizard_url, "pk", pk, reset=True ) return redirect(reverse(wizard_url, kwargs={"step": "final-" + wizard_url})) def reset_wizards(request): for wizard_class, url_name in ( (wizards.FindWizard, "find_creation"), (wizards.FindModificationWizard, "find_modification"), (wizards.FindDeletionWizard, "find_deletion"), (wizards.TreatmentWizard, "treatement_creation"), (wizards.TreatmentModificationWizard, "treatment_modification"), (wizards.TreatmentDeletionWizard, "treatment_deletion"), (wizards.TreatmentAdministrativeActWizard, "treatment_admacttreatment"), ( wizards.TreatmentEditAdministrativeActWizard, "treatment_admacttreatment_modification", ), (wizards.TreatmentDeletionWizard, "treatment_admacttreatment_deletion"), (wizards.TreatmentFileWizard, "treatmentfile_creation"), (wizards.TreatmentFileModificationWizard, "treatmentfile_modification"), (wizards.TreatmentFileDeletionWizard, "treatmentfile_deletion"), ( wizards.TreatmentFileAdministrativeActWizard, "treatmentfle_admacttreatmentfle", ), ( wizards.TreatmentFileEditAdministrativeActWizard, "treatmentfle_admacttreatmentfle_modification", ), (AdministrativeActDeletionWizard, "treatmentfle_admacttreatmentfle_deletion"), ): wizard_class.session_reset(request, url_name) class QAFindForm(QAItemEditForm): model = models.Find form_class = forms.QAFindFormMulti template_name = "ishtar/forms/qa_find_edit_form.html" class QAFindBasketFormView(QAItemForm): template_name = "ishtar/forms/qa_find_basket.html" model = models.Find form_class = forms.QAFindBasketForm page_name = _("Basket") modal_size = "small" base_url = "find-qa-basket" def get_form_kwargs(self): kwargs = super(QAFindBasketFormView, self).get_form_kwargs() kwargs["user"] = self.request.user return kwargs def form_valid(self, form): form.save(self.items) return HttpResponseRedirect(reverse("success")) class QAFindDuplicateFormView(QAItemForm): template_name = "ishtar/forms/qa_find_duplicate.html" model = models.Find page_name = _("Duplicate") form_class = forms.QAFindDuplicateForm base_url = "find-qa-duplicate" def get_form_kwargs(self): kwargs = super(QAFindDuplicateFormView, self).get_form_kwargs() kwargs["user"] = self.request.user return kwargs def form_valid(self, form): form.save() return HttpResponseRedirect(reverse("success")) def get_context_data(self, **kwargs): data = super(QAFindDuplicateFormView, self).get_context_data(**kwargs) data["action_name"] = _("Duplicate") bf = self.items[0].get_first_base_find() if bf: data["context_record"] = bf.context_record data["operation"] = bf.context_record.operation return data class QAFindTreatmentFormView(QAItemForm): template_name = "ishtar/forms/qa_find_treatment.html" model = models.Find form_class = forms.QAFindTreatmentForm page_name = _("Packaging") base_url = "find-qa-packaging" def dispatch(self, request, *args, **kwargs): returned = super(QAFindTreatmentFormView, self).dispatch( request, *args, **kwargs ) for item in self.items: if item.is_locked(request.user): return HttpResponseRedirect(reverse("qa-not-available")) return returned def get_form_kwargs(self): kwargs = super(QAFindTreatmentFormView, self).get_form_kwargs() kwargs["user"] = self.request.user kwargs["prefix"] = "qa-packaging" return kwargs def form_valid(self, form): form.save(self.items, self.request.user) return HttpResponseRedirect(reverse("success")) class QAFindbasketDuplicateFormView(QAItemForm): template_name = "ishtar/forms/qa_findbasket_duplicate.html" model = models.FindBasket page_name = _("Duplicate") modal_size = "small" form_class = forms.QAFindbasketDuplicateForm base_url = "findbasket-qa-duplicate" def get_form_kwargs(self): kwargs = super(QAFindbasketDuplicateFormView, self).get_form_kwargs() kwargs["user"] = self.request.user return kwargs def form_valid(self, form): form.save() return HttpResponseRedirect(reverse("success")) def get_context_data(self, **kwargs): data = super(QAFindbasketDuplicateFormView, self).get_context_data(**kwargs) data["action_name"] = _("Duplicate") return data class QAFindLockView(QABaseLockView): model = models.Find base_url = "find-qa-lock" class PublicFindAPI(APIView): authentication_classes = (authentication.TokenAuthentication,) permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): empty = models.Find.objects.filter(pk=None) basket_slug = self.request.GET.get("basket", None) if not basket_slug: return empty try: basket = models.FindBasket.objects.get(slug=basket_slug, public=True) except models.FindBasket.DoesNotExist: return empty q = ( models.FindBasket.items.through.objects.filter(findbasket_id=basket.id) .values("find_id") .order_by("id") ) id_list = [bi["find_id"] for bi in q] clauses = " ".join( "WHEN id=%s THEN %s" % (pk, i) for i, pk in enumerate(id_list) ) ordering = "CASE {} END".format(clauses) return models.Find.objects.filter(id__in=id_list).extra( select={"ordering": ordering}, order_by=("ordering",) ) def get(self, request, format=None): serializer = PublicSerializer(self.get_queryset(), many=True) return Response(serializer.data)