#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2010-2017 É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. import json from jinja2 import TemplateSyntaxError from django.conf import settings from django.core.urlresolvers import reverse from django.db.models import Q from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.shortcuts import render, redirect from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy from archaeological_operations import models from archaeological_operations import forms from archaeological_operations import wizards from ishtar_common.forms import ClosingDateFormSelection, FinalForm, \ FinalDeleteForm 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, \ QABaseLockView, wizard_is_available, QAItemForm from ishtar_common.views_item import get_item, show_item, revert_item, \ new_qa_item from ishtar_common.wizards import SearchWizard def autocomplete_patriarche(request): if (not request.user.has_perm('ishtar_common.view_operation', models.Operation) and not request.user.has_perm('ishtar_common.view_own_operation', models.Operation) and not request.user.ishtaruser.has_right( 'operation_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 q in q.split(' '): query &= Q(code_patriarche__startswith=q) limit = 15 operations = models.Operation.objects\ .filter(query).order_by('code_patriarche')[:limit] data = json.dumps([{'id': operation.code_patriarche, 'value': operation.code_patriarche} for operation in operations]) return HttpResponse(data, content_type='text/plain') def autocomplete_archaeologicalsite(request): if (not request.user.has_perm( 'archaeological_operations.view_archaeologicalsite', models.ArchaeologicalSite) and not request.user.has_perm( 'archaeological_operations.view_own_archaeologicalsite', models.ArchaeologicalSite)): 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 q in q.split(' '): qt = Q(reference__icontains=q) | Q(name__icontains=q) query = query & qt limit = 15 sites = models.ArchaeologicalSite.objects.filter( query).order_by('reference')[:limit] data = json.dumps([{'id': site.pk, 'value': str(site)[:60]} for site in sites]) return HttpResponse(data, content_type='text/plain') new_archaeologicalsite = new_qa_item(models.ArchaeologicalSite, forms.ArchaeologicalSiteForm, many=True) def autocomplete_operation(request): # person_types = request.user.ishtaruser.person.person_type if (not request.user.has_perm('ishtar_common.view_operation', models.Operation) and not request.user.has_perm( 'ishtar_common.view_own_operation', models.Operation) and not request.user.ishtaruser.has_right( 'operation_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 q in q.split(' '): extra = Q(towns__name__icontains=q) | Q(common_name__icontains=q) try: int(q) extra = extra | Q(year=q) | Q(operation_code=q) except ValueError: pass if settings.COUNTRY == 'fr': if q.startswith('OA'): q = q[2:] try: int(q) extra |= Q(code_patriarche__contains=q) except ValueError: pass query = query & extra limit = 15 operations = models.Operation.objects.filter(query)[:limit] data = json.dumps([{'id': operation.pk, 'value': str(operation)} for operation in operations]) return HttpResponse(data, content_type='text/plain') def get_available_operation_code(request, year=None): if not request.user.has_perm( 'ishtar_common.view_operation', models.Operation)\ and not request.user.has_perm( 'ishtar_common.view_own_operation', models.Operation): return HttpResponse(content_type='text/plain') data = json.dumps({'id': models.Operation.get_available_operation_code(year)}) return HttpResponse(data, content_type='text/plain') get_operation = get_item(models.Operation, 'get_operation', 'operation', search_form=forms.OperationSelect) show_operation = show_item(models.Operation, 'operation') revert_operation = revert_item(models.Operation) get_administrativeactop = get_item( models.AdministrativeAct, 'get_administrativeactop', 'administrativeactop', base_request={"operation__pk__isnull": False}) get_administrativeact = get_item( models.AdministrativeAct, 'get_administrativeact', 'administrativeact') show_administrativeact = show_item(models.AdministrativeAct, 'administrativeact') def dashboard_operation(request, *args, **kwargs): """ Operation dashboard """ dct = {'dashboard': models.OperationDashboard()} return render(request, 'ishtar/dashboards/dashboard_operation.html', dct) operation_search_wizard = wizards.OperationSearch.as_view( [('general-operation_search', forms.OperationFormSelection)], label=_(u"Operation search"), url_name='operation_search',) wizard_steps = [ ('filechoice-operation_creation', forms.OperationFormFileChoice), ('general-operation_creation', forms.OperationFormGeneral), ('judiciary-operation_creation', forms.CourtOrderedSeizureForm), ('collaborators-operation_creation', forms.CollaboratorForm), ('archaeologicalsite-operation_creation', forms.ArchaeologicalSiteFormSet), ('preventive-operation_creation', forms.OperationFormPreventive), ('preventivediag-operation_creation', forms.OperationFormPreventiveDiag), ('townsgeneral-operation_creation', forms.TownFormset), ('towns-operation_creation', forms.SelectedTownFormset), ('parcelsgeneral-operation_creation', forms.SelectedParcelGeneralFormSet), ('parcels-operation_creation', forms.SelectedParcelFormSet), ('remains-operation_creation', forms.RemainForm), ('periods-operation_creation', forms.PeriodForm), ('relations-operation_creation', forms.RecordRelationsFormSet), ('abstract-operation_creation', forms.OperationFormAbstract), ('final-operation_creation', FinalForm)] def get_check_files_for_operation(other_check=None): def func(self): if not get_current_profile().files or \ not check_rights_condition(['view_file'])(self): return False if not other_check: return True return other_check(self) return func check_files_for_operation = get_check_files_for_operation() ope_crea_condition_dict = { 'filechoice-operation_creation': check_files_for_operation, 'judiciary-operation_creation': wizards.is_judiciary( 'general-operation_creation', models.OperationType, 'operation_type', ), 'preventive-operation_creation': get_check_files_for_operation( wizards.is_preventive('general-operation_creation', models.OperationType, 'operation_type', 'prev_excavation')), 'preventivediag-operation_creation': get_check_files_for_operation( wizards.is_preventive('general-operation_creation', models.OperationType, 'operation_type', 'arch_diagnostic')), 'townsgeneral-operation_creation': wizards.has_associated_file( 'filechoice-operation_creation', negate=True), 'towns-operation_creation': wizards.has_associated_file( 'filechoice-operation_creation'), 'parcelsgeneral-operation_creation': wizards.has_associated_file( 'filechoice-operation_creation', negate=True), 'parcels-operation_creation': wizards.has_associated_file( 'filechoice-operation_creation'), } operation_creation_wizard = wizards.OperationWizard.as_view( wizard_steps, label=_(u"New operation"), condition_dict=ope_crea_condition_dict, url_name='operation_creation',) operation_modif_wizard_steps = [ ('selec-operation_modification', forms.OperationFormSelection), ('general-operation_modification', forms.OperationFormModifGeneral), ('judiciary-operation_modification', forms.CourtOrderedSeizureForm), ('collaborators-operation_modification', forms.CollaboratorForm), ('archaeologicalsite-operation_modification', forms.ArchaeologicalSiteFormSet), ('preventive-operation_modification', forms.OperationFormPreventive), ('preventivediag-operation_modification', forms.OperationFormPreventiveDiag), ('towns-operation_modification', forms.SelectedTownFormset), ('townsgeneral-operation_modification', forms.TownFormset), ('parcels-operation_modification', forms.SelectedParcelFormSet), ('parcelsgeneral-operation_modification', forms.SelectedParcelGeneralFormSet), ('remains-operation_modification', forms.RemainForm), ('periods-operation_modification', forms.PeriodForm), ('relations-operation_modification', forms.RecordRelationsFormSet), ('abstract-operation_modification', forms.OperationFormAbstract), ('final-operation_modification', FinalForm) ] ope_modif_condition_dict = { 'preventive-operation_modification': get_check_files_for_operation( wizards.is_preventive('general-operation_modification', models.OperationType, 'operation_type', 'prev_excavation')), 'preventivediag-operation_modification': get_check_files_for_operation( wizards.is_preventive('general-operation_modification', models.OperationType, 'operation_type', 'arch_diagnostic')), 'judiciary-operation_modification': wizards.is_judiciary( 'general-operation_modification', models.OperationType, 'operation_type', ), 'townsgeneral-operation_modification': wizards.has_associated_file( 'general-operation_modification', negate=True), 'towns-operation_modification': wizards.has_associated_file( 'general-operation_modification'), 'parcelsgeneral-operation_modification': wizards.has_associated_file( 'general-operation_modification', negate=True), 'parcels-operation_modification': wizards.has_associated_file( 'general-operation_modification'), } operation_modification_wizard = wizards.OperationModificationWizard.as_view( operation_modif_wizard_steps, label=_(u"Operation modification"), condition_dict=ope_modif_condition_dict, url_name='operation_modification',) def operation_modify(request, pk): if not wizard_is_available(operation_modification_wizard, request, models.Operation, pk): return HttpResponseRedirect("/") wizard_url = 'operation_modification' wizards.OperationModificationWizard.session_set_value( request, 'selec-' + wizard_url, 'pk', pk, reset=True) return redirect(reverse(wizard_url, kwargs={'step': 'general-' + wizard_url})) def operation_add(request, file_id): operation_creation_wizard(request) wizards.OperationWizard.session_set_value( request, 'filechoice-operation_creation', 'associated_file', file_id, reset=True) return redirect(reverse('operation_creation', kwargs={'step': 'general-operation_creation'})) operation_closing_steps = [ ('selec-operation_closing', forms.OperationFormSelection), ('date-operation_closing', ClosingDateFormSelection), ('final-operation_closing', forms.FinalOperationClosingForm)] operation_closing_wizard = wizards.OperationClosingWizard.as_view( operation_closing_steps, label=_(u"Operation closing"), url_name='operation_closing',) operation_deletion_steps = [ ('selec-operation_deletion', forms.OperationFormMultiSelection), ('final-operation_deletion', forms.OperationDeletionForm) ] operation_deletion_wizard = wizards.OperationDeletionWizard.as_view( operation_deletion_steps, label=_(u"Operation deletion"), url_name='operation_deletion',) def operation_delete(request, pk): if not wizard_is_available(operation_deletion_wizard, request, models.Operation, pk): return HttpResponseRedirect("/") wizard_url = 'operation_deletion' wizards.OperationDeletionWizard.session_set_value( request, 'selec-' + wizard_url, 'pks', pk, reset=True) return redirect(reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) # archaeological sites def site_extra_context(request, item): return {'SITE_LABEL': IshtarSiteProfile.get_default_site_label()} get_site = get_item(models.ArchaeologicalSite, 'get_site', 'site', search_form=forms.SiteSelect) show_site = show_item( models.ArchaeologicalSite, 'site', extra_dct=site_extra_context ) revert_site = revert_item(models.ArchaeologicalSite) site_search_wizard = wizards.SiteSearch.as_view( [('general-site_search', forms.SiteFormSelection)], url_name='site_search', ) site_creation_steps = [ ('general-site_creation', forms.SiteForm), ('towns-site_creation', forms.SiteTownFormset), ('underwater-site_creation', forms.SiteUnderwaterForm), ('final-site_creation', FinalForm) ] site_creation_wizard = wizards.SiteWizard.as_view( site_creation_steps, condition_dict={'underwater-site_creation': forms.check_underwater_module}, url_name='site_creation', ) site_modification_steps = [ ('selec-site_modification', forms.SiteFormSelection), ('general-site_modification', forms.SiteForm), ('towns-site_modification', forms.SiteTownFormset), ('underwater-site_modification', forms.SiteUnderwaterForm), ('final-site_modification', FinalForm) ] site_modification_wizard = wizards.SiteModificationWizard.as_view( site_modification_steps, condition_dict={ 'underwater-site_modification': forms.check_underwater_module}, url_name='site_modification', ) def site_modify(request, pk): if not wizard_is_available(site_modification_wizard, request, models.ArchaeologicalSite, pk): return HttpResponseRedirect("/") wizard_url = 'site_modification' wizards.SiteModificationWizard.session_set_value( request, 'selec-' + wizard_url, 'pk', pk, reset=True) return redirect(reverse(wizard_url, kwargs={'step': 'general-' + wizard_url})) site_deletion_steps = [ ('selec-site_deletion', forms.SiteFormMultiSelection), ('final-site_deletion', FinalDeleteForm) ] site_deletion_wizard = wizards.SiteDeletionWizard.as_view( site_deletion_steps, label=_(u"Site deletion"), url_name='site_deletion',) def site_delete(request, pk): if not wizard_is_available(site_deletion_wizard, request, models.ArchaeologicalSite, pk): return HttpResponseRedirect("/") wizard_url = 'site_deletion' wizards.SiteDeletionWizard.session_set_value( request, 'selec-' + wizard_url, 'pks', pk, reset=True) return redirect(reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) operation_administrativeactop_search_wizard = wizards.SearchWizard.as_view([ ('general-operation_administrativeactop_search', forms.AdministrativeActOpeFormSelection)], label=_(u"Administrative act search"), url_name='operation_administrativeactop_search',) administrativeactop_steps = [ ('selec-operation_administrativeactop', forms.OperationFormSelection), ('administrativeact-operation_administrativeactop', forms.AdministrativeActOpeForm), ('final-operation_administrativeactop', FinalForm)] operation_administrativeactop_wizard = \ wizards.OperationAdministrativeActWizard.as_view( administrativeactop_steps, label=_(u"Operation: new administrative act"), url_name='operation_administrativeactop',) operation_administrativeactop_modification_wizard = \ wizards.OperationEditAdministrativeActWizard.as_view([ ('selec-operation_administrativeactop_modification', forms.AdministrativeActOpeFormSelection), ('administrativeact-operation_administrativeactop_modification', forms.AdministrativeActOpeModifForm), ('final-operation_administrativeactop_modification', FinalForm)], label=_("Operation: administrative act modification"), url_name='operation_administrativeactop_modification',) def operation_administrativeactop_modify(request, pk): if not wizard_is_available( operation_administrativeactop_modification_wizard, request, models.AdministrativeAct, pk): return HttpResponseRedirect("/") wizard_url = 'operation_administrativeactop_modification' wizards.OperationEditAdministrativeActWizard.session_set_value( request, 'selec-' + wizard_url, 'pk', pk, reset=True) return redirect( reverse(wizard_url, kwargs={'step': 'administrativeact-' + wizard_url})) operation_administrativeactop_deletion_wizard = \ wizards.AdministrativeActDeletionWizard.as_view([ ('selec-operation_administrativeactop_deletion', forms.AdministrativeActOpeFormSelection), ('final-operation_administrativeactop_deletion', forms.FinalAdministrativeActDeleteForm)], label=_(u"Operation: administrative act deletion"), url_name='operation_administrativeactop_deletion',) def operation_administrativeactop_delete(request, pk): if not wizard_is_available( operation_administrativeactop_deletion_wizard, request, models.AdministrativeAct, pk): return HttpResponseRedirect("/") wizard_url = 'operation_administrativeactop_deletion' wizards.AdministrativeActDeletionWizard.session_set_value( request, 'selec-' + wizard_url, 'pk', pk, reset=True) return redirect( reverse(wizard_url, kwargs={'step': 'final-' + wizard_url})) administrativact_register_wizard = SearchWizard.as_view([ ('general-administrativact_register', forms.AdministrativeActRegisterFormSelection)], label=pgettext_lazy('admin act register', u"Register"), url_name='administrativact_register',) generatedoc_administrativeactop = gen_generate_doc(models.AdministrativeAct) def administrativeactfile_document( request, file=False, treatment=False, treatment_file=False): search_form = forms.AdministrativeActOpeFormSelection document_type = 'O' if file: from archaeological_files.forms import \ AdministrativeActFileFormSelection search_form = AdministrativeActFileFormSelection document_type = 'F' elif treatment: from archaeological_finds.forms import \ AdministrativeActTreatmentFormSelection search_form = AdministrativeActTreatmentFormSelection document_type = 'T' elif treatment_file: from archaeological_finds.forms import \ AdministrativeActTreatmentFileFormSelection search_form = AdministrativeActTreatmentFileFormSelection document_type = 'TF' if not request.user.has_perm('view_administrativeact', models.AdministrativeAct): return HttpResponse(content_type='text/plain') dct = {} DocumentGenerationAdminActForm = forms.DocumentGenerationAdminActForm if request.POST: dct['search_form'] = search_form(request.POST) dct['template_form'] = DocumentGenerationAdminActForm( document_type=document_type) c_object = None try: if dct['search_form'].is_valid(): c_object = \ DocumentGenerationAdminActForm._associated_model\ .objects.get(pk=dct['search_form'].cleaned_data.get('pk')) except DocumentGenerationAdminActForm._associated_model.DoesNotExist: pass if c_object: dct['template_form'] = DocumentGenerationAdminActForm( request.POST, document_type=document_type, obj=c_object) if dct['template_form'].is_valid(): try: return generatedoc_administrativeactop( request, dct['search_form'].cleaned_data.get('pk'), dct['template_form'].cleaned_data.get( 'document_template')) except TemplateSyntaxError: dct['search_form'] = search_form() try: template = DocumentTemplate.objects.get(pk=dct[ 'template_form'].cleaned_data.get( 'document_template')).name except DocumentTemplate.DoesNotExist: template = "" dct['template_form'] = DocumentGenerationAdminActForm( document_type=document_type) dct['template_error'] = str(_( "Syntax error on the source template \"{}\" - " "contact your administrator and ask him to check " "the syntax of this document.")).format(template) else: dct['search_form'] = search_form() dct['template_form'] = DocumentGenerationAdminActForm( document_type=document_type) return render(request, 'ishtar/administrativeact_document.html', dct) def reset_wizards(request): for wizard_class, url_name in ( (wizards.OperationWizard, 'operation_creation'), (wizards.OperationModificationWizard, 'operation_modification'), (wizards.OperationClosingWizard, 'operation_closing'), (wizards.OperationDeletionWizard, 'operation_deletion_wizard'), (wizards.OperationAdministrativeActWizard, 'operation_administrativeactop'), (wizards.OperationEditAdministrativeActWizard, 'operation_administrativeactop_modification'), (wizards.AdministrativeActDeletionWizard, 'operation_administrativeactop_deletion'),): wizard_class.session_reset(request, url_name) class QAOperationForm(QAItemEditForm): model = models.Operation form_class = forms.QAOperationFormMulti class QAOperationLockView(QABaseLockView): model = models.Operation base_url = "operation-qa-lock" class QASiteLockView(QABaseLockView): model = models.ArchaeologicalSite base_url = "site-qa-lock" class QAOperationdDuplicateFormView(QAItemForm): template_name = 'ishtar/forms/qa_operation_duplicate.html' model = models.Operation page_name = _("Duplicate") form_class = forms.QAOperationDuplicateForm base_url = "operation-qa-duplicate" def get_form_kwargs(self): kwargs = super(QAOperationdDuplicateFormView, 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(QAOperationdDuplicateFormView, self).get_context_data( **kwargs) data['action_name'] = _("Duplicate") return data class QAArchaeologicalSiteDuplicateFormView(QAItemForm): template_name = 'ishtar/forms/qa_site_duplicate.html' model = models.ArchaeologicalSite page_name = _("Duplicate") form_class = forms.QAArchaeologicalSiteDuplicateForm base_url = "site-qa-duplicate" def get_form_kwargs(self): kwargs = super(QAArchaeologicalSiteDuplicateFormView, 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(QAArchaeologicalSiteDuplicateFormView, self).get_context_data(**kwargs) data['action_name'] = _("Duplicate") return data