diff options
Diffstat (limited to 'archaeological_files')
-rw-r--r-- | archaeological_files/admin.py | 42 | ||||
-rw-r--r-- | archaeological_files/forms.py | 389 | ||||
-rw-r--r-- | archaeological_files/ishtar_menu.py | 8 | ||||
-rw-r--r-- | archaeological_files/models.py | 124 | ||||
-rw-r--r-- | archaeological_files/urls.py | 64 | ||||
-rw-r--r-- | archaeological_files/views.py | 66 |
6 files changed, 688 insertions, 5 deletions
diff --git a/archaeological_files/admin.py b/archaeological_files/admin.py new file mode 100644 index 000000000..339b19661 --- /dev/null +++ b/archaeological_files/admin.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> + +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +from django.conf import settings +from django.contrib import admin + +from ishtar_common.admin import HistorizedObjectAdmin + +import models + +class FileAdmin(HistorizedObjectAdmin): + list_display = ['year', 'numeric_reference', 'internal_reference', + 'end_date', 'file_type', 'general_contractor',] + if settings.COUNTRY == 'fr': + list_display += ['saisine_type', 'reference_number'] + list_filter = ("file_type", "year",) + search_fields = ('towns__name',) + model = models.File + +admin.site.register(models.File, FileAdmin) + +basic_models = [models.FileType, models.PermitType] +if settings.COUNTRY == 'fr': + basic_models.append(models.SaisineType) +for model in basic_models: + admin.site.register(model) diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py new file mode 100644 index 000000000..368c57843 --- /dev/null +++ b/archaeological_files/forms.py @@ -0,0 +1,389 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> + +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +""" +Files forms definitions +""" +import datetime + +from django import forms +from django.conf import settings +from django.core import validators +from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Max +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.utils.translation import ugettext_lazy as _ + +from ishtar_common.models import Town +import models +from ishtar_common.views import Wizard +from ishtar_common.forms import FinalForm, FormSet, ClosingWizard, \ + ClosingDateFormSelection, SearchWizard, formset_factory, get_now, \ + reverse_lazy +from ishtar_common.forms_common import TownFormset, ParcelFormSet, \ + get_town_field, get_person_field +from archaeological_operations.forms import OperationAdministrativeActWizard, \ + AdministrativeActOpeForm, AdministrativeActOpeFormSelection, \ + AdministrativeActDeletionWizard, FinalAdministrativeActDeleteForm, \ + is_preventive +from ishtar_common import widgets + +class FileWizard(Wizard): + model = models.File + object_parcel_type = 'associated_file' + + def get_form(self, request, storage, step=None, data=None, files=None): + """ + Manage towns + """ + if data: + data = data.copy() + else: + data = {} + # manage the dynamic choice of towns + if not step: + step = self.determine_step(request, storage) + form = self.get_form_list(request, storage)[step] + town_form_key = 'towns-' + self.url_name + if step.startswith('parcels-') and hasattr(form, 'management_form') \ + and self.session_has_key(request, storage, town_form_key): + towns = [] + qdict = request.session[storage.prefix]['step_data'][town_form_key] + for k in qdict.keys(): + if k.endswith("town") and qdict[k]: + try: + town = Town.objects.get(pk=int(qdict[k])) + towns.append((town.pk, unicode(town))) + except (ObjectDoesNotExist, ValueError): + pass + data['TOWNS'] = sorted(towns, key=lambda x:x[1]) + form = super(FileWizard, self).get_form(request, storage, step, data, + files) + return form + + def get_extra_model(self, dct, request, storage, form_list): + dct = super(FileWizard, self).get_extra_model(dct, request, storage, + form_list) + if not dct['numeric_reference']: + current_ref = models.File.objects.filter(year=dct['year'] + ).aggregate(Max('numeric_reference'))["numeric_reference__max"] + dct['numeric_reference'] = current_ref and current_ref + 1 or 1 + return dct + + def done(self, request, storage, form_list, **kwargs): + ''' + Save parcels + ''' + r = super(FileWizard, self).done(request, storage, form_list, + return_object=True, **kwargs) + if type(r) not in (list, tuple) or len(r) != 2: + return r + obj, res = r + obj.parcels.clear() + for form in form_list: + if not hasattr(form, 'prefix') \ + or not form.prefix.startswith('parcels-') \ + or not hasattr(form, 'forms'): + continue + for frm in form.forms: + if not frm.is_valid(): + continue + dct = frm.cleaned_data.copy() + if 'parcel' in dct: + try: + parcel = models.Parcel.objects.get(pk=dct['parcel']) + setattr(parcel, self.object_parcel_type, obj) + parcel.save() + except (ValueError, ObjectDoesNotExist): + continue + continue + try: + dct['town'] = models.Town.objects.get(pk=int(dct['town'])) + except (ValueError, ObjectDoesNotExist): + continue + dct['associated_file'], dct['operation'] = None, None + dct[self.object_parcel_type] = obj + if 'DELETE' in dct: + dct.pop('DELETE') + parcel = models.Parcel.objects.filter(**dct).count() + if not parcel: + dct['history_modifier'] = request.user + parcel = models.Parcel(**dct) + parcel.save() + return res + +class FileSelect(forms.Form): + towns = get_town_field() + in_charge = get_person_field(label=_(u"Person in charge"), + person_type='sra_agent') + file_type = forms.ChoiceField(label=_("File type"), + choices=models.FileType.get_types()) + saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[]) + year = forms.IntegerField(label=_("Year")) + + def __init__(self, *args, **kwargs): + super(FileSelect, self).__init__(*args, **kwargs) + self.fields['saisine_type'].choices = models.SaisineType.get_types() + self.fields['saisine_type'].help_text = models.SaisineType.get_help() + +class FileFormSelection(forms.Form): + form_label = _("Archaeological file search") + associated_models = {'pk':models.File} + currents = {'pk':models.File} + pk = forms.IntegerField(label="", required=False, + widget=widgets.JQueryJqGrid(reverse_lazy('get-file'), + FileSelect(), models.File, source_full=reverse_lazy('get-file-full')), + validators=[models.valid_id(models.File)]) + + def clean(self): + cleaned_data = self.cleaned_data + if 'pk' not in cleaned_data or not cleaned_data['pk']: + raise forms.ValidationError(_(u"You should select a file.")) + return cleaned_data + +class FileFormGeneral(forms.Form): + form_label = _("General") + associated_models = {'in_charge':models.Person, + 'related_file':models.File, + 'file_type':models.FileType} + in_charge = forms.IntegerField(label=_("Person in charge"), + widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person', + args=[models.PersonType.objects.get(txt_idx='sra_agent').pk]), + associated_model=models.Person, new=True), + validators=[models.valid_id(models.Person)]) + year = forms.IntegerField(label=_("Year"), + initial=lambda:datetime.datetime.now().year, + validators=[validators.MinValueValidator(1900), + validators.MaxValueValidator(2100)]) + numeric_reference = forms.IntegerField(label=_("Numeric reference"), + widget=forms.HiddenInput, required=False) + internal_reference = forms.CharField(label=_(u"Internal reference"), + max_length=60, + validators=[models.is_unique(models.File, 'internal_reference')]) + creation_date = forms.DateField(label=_(u"Creation date"), + initial=get_now, widget=widgets.JQueryDate) + file_type = forms.ChoiceField(label=_("File type"), + choices=models.FileType.get_types()) + related_file = forms.IntegerField(label=_("Related file"), required=False, + widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'), + associated_model=models.File), + validators=[models.valid_id(models.File)]) + comment = forms.CharField(label=_(u"Comment"), widget=forms.Textarea, + required=False) + +class FileFormGeneralRO(FileFormGeneral): + year = forms.IntegerField(label=_(u"Year"), + widget=forms.TextInput(attrs={'readonly':True})) + numeric_reference = forms.IntegerField(label=_(u"Numeric reference"), + widget=forms.TextInput(attrs={'readonly':True})) + internal_reference = forms.CharField(label=_(u"Internal reference"), + widget=forms.TextInput(attrs={'readonly':True},)) + +class FileFormAddress(forms.Form): + form_label = _(u"Address") + associated_models = {'town':models.Town} + total_surface = forms.IntegerField(required=False, + widget=widgets.AreaWidget, + label=_(u"Total surface (m²)"), + validators=[validators.MinValueValidator(0), + validators.MaxValueValidator(999999999)]) + address = forms.CharField(label=_(u"Main address"), widget=forms.Textarea) + address_complement = forms.CharField(label=_(u"Main address - complement"), + required=False) + postal_code = forms.CharField(label=_(u"Main address - postal code"), + max_length=10) + +class FileFormPreventive(forms.Form): + form_label = _(u"Preventive informations") + associated_models = {'general_contractor':models.Person, + 'saisine_type':models.SaisineType, + 'permit_type':models.PermitType, + 'town_planning_service':models.Organization} + general_contractor = forms.IntegerField(label=_(u"General contractor"), + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-person', + args=[models.PersonType.objects.get(txt_idx='general_contractor').pk]), + associated_model=models.Person, new=True), + validators=[models.valid_id(models.Person)]) + town_planning_service = forms.IntegerField(required=False, + label=_(u"Town planning service"), + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-organization', + args=[models.OrganizationType.objects.get(txt_idx='planning_service').pk]), + associated_model=models.Organization, new=True), + validators=[models.valid_id(models.Organization)]) + permit_type = forms.ChoiceField(label=_(u"Permit type"), required=False, + choices=models.PermitType.get_types()) + permit_reference = forms.CharField(label=_(u"Permit reference"), + required=False, validators=[validators.MaxLengthValidator(60)]) + total_developed_surface = forms.IntegerField(widget=widgets.AreaWidget, + label=_(u"Total developed surface (m²)"), + required=False, validators=[validators.MinValueValidator(0), + validators.MaxValueValidator(999999999)]) + if settings.COUNTRY == 'fr': + saisine_type = forms.ChoiceField(label=_(u"Saisine type"), + choices=[]) + reception_date = forms.DateField(label=_(u"Reception date"), + initial=get_now, widget=widgets.JQueryDate) + def __init__(self, *args, **kwargs): + super(FileFormPreventive, self).__init__(*args, **kwargs) + self.fields['saisine_type'].choices = models.SaisineType.get_types() + self.fields['saisine_type'].help_text = models.SaisineType.get_help() + +file_search_wizard = SearchWizard([('general-file_search', FileFormSelection)], + url_name='file_search',) + +file_creation_wizard = FileWizard([ + ('general-file_creation', FileFormGeneral), + ('address-file_creation', FileFormAddress), + ('towns-file_creation', TownFormset), + ('parcels-file_creation', ParcelFormSet), + ('preventive-file_creation', FileFormPreventive), + ('final-file_creation', FinalForm)], + condition_list={ +'preventive-file_creation':is_preventive('general-file_creation', + models.FileType, type_key='file_type') + }, + url_name='file_creation',) + +class FileModificationWizard(FileWizard): + modification = True + +file_modification_wizard = FileModificationWizard([ + ('selec-file_modification', FileFormSelection), + ('general-file_modification', FileFormGeneralRO), + ('adress-file_modification', FileFormAddress), + ('towns-file_modification', TownFormset), + ('parcels-file_modification', ParcelFormSet), + ('preventive-file_modification', FileFormPreventive), + ('final-file_modification', FinalForm)], + condition_list={ +'preventive-file_modification':is_preventive('general-file_modification', + models.FileType, type_key='file_type') + }, + url_name='file_modification',) + +class FileClosingWizard(ClosingWizard): + model = models.File + fields = ['year', 'numeric_reference', 'internal_reference', + 'file_type', 'in_charge', 'general_contractor', 'creation_date', + 'reception_date', 'total_surface', 'total_developed_surface', + 'address', 'address_complement', 'postal_code', 'comment'] + if settings.COUNTRY == 'fr': + fields += ['saisine_type', 'reference_number'] + fields += ['towns'] + +class FinalFileClosingForm(FinalForm): + confirm_msg = " " + confirm_end_msg = _(u"Would you like to close this archaeological file?") + +file_closing_wizard = FileClosingWizard([ + ('selec-file_closing', FileFormSelection), + ('date-file_closing', ClosingDateFormSelection), + ('final-file_closing', FinalFileClosingForm)], + url_name='file_closing',) + +class FileDeletionWizard(FileClosingWizard): + def get_formated_datas(self, forms): + datas = super(FileDeletionWizard, self).get_formated_datas(forms) + datas.append((_("Associated operations"), [])) + for operation in models.Operation.objects.filter( + associated_file=self.current_obj).all(): + if operation.end_date: + datas[-1][1].append(('', unicode(operation))) + return datas + + def done(self, request, storage, form_list, **kwargs): + obj = self.get_current_object(request, storage) + for operation in models.Operation.objects.filter( + associated_file=obj).all(): + operation.delete() + obj.delete() + return render_to_response('wizard_done.html', {}, + context_instance=RequestContext(request)) + + +class FinalFileDeleteForm(FinalForm): + confirm_msg = " " + confirm_end_msg = _(u"Would you like to delete this archaelogical file ?") + +file_deletion_wizard = FileDeletionWizard([ + ('selec-file_deletion', FileFormSelection), + ('final-file_deletion', FinalFileDeleteForm)], + url_name='file_deletion',) + +class FileAdministrativeActWizard(OperationAdministrativeActWizard): + model = models.File + +class FileEditAdministrativeActWizard(FileAdministrativeActWizard): + model = models.AdministrativeAct + edit = True + def get_associated_item(self, request, storage, dct): + return self.get_current_object(request, storage).associated_file + +class AdministrativeActFileSelect(forms.Form): + associated_file__towns = get_town_field() + act_type = forms.ChoiceField(label=_("Act type"), choices=[]) + + def __init__(self, *args, **kwargs): + super(AdministrativeActFileSelect, self).__init__(*args, **kwargs) + self.fields['act_type'].choices = models.ActType.get_types( + dct={'intented_to':'F'}) + self.fields['act_type'].help_text = models.ActType.get_help( + dct={'intented_to':'F'}) + +class AdministrativeActFileFormSelection(AdministrativeActOpeFormSelection): + pk = forms.IntegerField(label="", required=False, + widget=widgets.JQueryJqGrid(reverse_lazy('get-administrativeactfile'), + AdministrativeActFileSelect(), models.AdministrativeAct, + table_cols='TABLE_COLS_FILE'), + validators=[models.valid_id(models.AdministrativeAct)]) + +class AdministrativeActFileForm(AdministrativeActOpeForm): + act_type = forms.ChoiceField(label=_(u"Act type"), choices=[]) + + def __init__(self, *args, **kwargs): + super(AdministrativeActFileForm, self).__init__(*args, **kwargs) + self.fields['act_type'].choices = models.ActType.get_types( + dct={'intented_to':'F'}) + self.fields['act_type'].help_text = models.ActType.get_help( + dct={'intented_to':'F'}) + +file_administrativeactfile_wizard = FileAdministrativeActWizard([ + ('selec-file_administrativeactfile', FileFormSelection), + ('administrativeact-file_administrativeactfile', AdministrativeActFileForm), + ('final-file_administrativeactfile', FinalForm)], + url_name='file_administrativeactfile',) + +file_administrativeactfile_modification_wizard = FileEditAdministrativeActWizard([ + ('selec-file_administrativeactfile_modification', + AdministrativeActFileFormSelection), + ('administrativeact-file_administrativeactfile_modification', + AdministrativeActFileForm), + ('final-file_administrativeactfile_modification', FinalForm)], + url_name='file_administrativeactfile_modification',) + +file_administrativeactfile_deletion_wizard = AdministrativeActDeletionWizard([ + ('selec-file_administrativeactfile_deletion', + AdministrativeActFileFormSelection), + ('final-file_administrativeactfile_deletion', + FinalAdministrativeActDeleteForm)], + url_name='file_administrativeactfile_deletion',) + diff --git a/archaeological_files/ishtar_menu.py b/archaeological_files/ishtar_menu.py index 370320f69..398b43f4b 100644 --- a/archaeological_files/ishtar_menu.py +++ b/archaeological_files/ishtar_menu.py @@ -21,14 +21,13 @@ from django.utils.translation import ugettext_lazy as _ from archaeological_operations.models import Operation from ishtar_common.menu_base import SectionItem, MenuItem -from ishtar_common.models import AdministrativeAct -import models +from archaeological_operations.models import AdministrativeAct -ORDER = 20 +import models MENU_SECTIONS = [ - SectionItem('file_management', _(u"Archaeological file"), + (20, SectionItem('file_management', _(u"Archaeological file"), childs=[ MenuItem('file_search', _(u"Search"), model=models.File, @@ -62,4 +61,5 @@ MENU_SECTIONS = [ access_controls=['delete_file', 'delete_own_file']), ],), ]), + ) ] diff --git a/archaeological_files/models.py b/archaeological_files/models.py index 68a65f6de..90f60fe64 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -24,7 +24,8 @@ from django.contrib.gis.db import models from django.utils.translation import ugettext_lazy as _, ugettext from ishtar_common.models import GeneralType, BaseHistorizedItem, \ - HistoricalRecords, OwnPerms, Person, Organization, Department, Town + HistoricalRecords, OwnPerms, Person, Organization, Department, Town, \ + Dashboard class FileType(GeneralType): class Meta: @@ -183,3 +184,124 @@ class FileByDepartment(models.Model): class Meta: managed = False db_table = 'file_department' + +class FileDashboard: + def __init__(self): + main_dashboard = Dashboard(File) + + self.total_number = main_dashboard.total_number + + types = File.objects.values('file_type', 'file_type__label') + self.types = types.annotate(number=Count('pk')).order_by('file_type') + + by_year = File.objects.extra( + {'date':"date_trunc('year', creation_date)"}) + self.by_year = by_year.values('date')\ + .annotate(number=Count('pk')).order_by('-date') + + now = datetime.date.today() + limit = datetime.date(now.year, now.month, 1) - datetime.timedelta(365) + by_month = File.objects.filter(creation_date__gt=limit).extra( + {'date':"date_trunc('month', creation_date)"}) + self.by_month = by_month.values('date')\ + .annotate(number=Count('pk')).order_by('-date') + + # research + self.research = {} + prog_type = FileType.objects.get(txt_idx='prog') + researchs = File.objects.filter(file_type=prog_type) + self.research['total_number'] = researchs.count() + by_year = researchs.extra({'date':"date_trunc('year', creation_date)"}) + self.research['by_year'] = by_year.values('date')\ + .annotate(number=Count('pk'))\ + .order_by('-date') + by_month = researchs.filter(creation_date__gt=limit)\ + .extra({'date':"date_trunc('month', creation_date)"}) + self.research['by_month'] = by_month.values('date')\ + .annotate(number=Count('pk'))\ + .order_by('-date') + + self.research['by_dpt'] = FileByDepartment.objects\ + .filter(file__file_type=prog_type, + department__isnull=False)\ + .values('department__label')\ + .annotate(number=Count('file'))\ + .order_by('department__label') + FileTown = File.towns.through + self.research['towns'] = FileTown.objects\ + .filter(file__file_type=prog_type)\ + .values('town__name')\ + .annotate(number=Count('file'))\ + .order_by('-number','town__name')[:10] + + # rescue + rescue_type = FileType.objects.get(txt_idx='preventive') + rescues = File.objects.filter(file_type=rescue_type) + self.rescue = {} + self.rescue['total_number'] = rescues.count() + self.rescue['saisine'] = rescues.values('saisine_type__label')\ + .annotate(number=Count('pk'))\ + .order_by('saisine_type__label') + self.rescue['administrative_act'] = AdministrativeAct.objects\ + .filter(associated_file__isnull=False)\ + .values('act_type__label')\ + .annotate(number=Count('pk'))\ + .order_by('act_type__pk') + + by_year = rescues.extra({'date':"date_trunc('year', creation_date)"}) + self.rescue['by_year'] = by_year.values('date')\ + .annotate(number=Count('pk'))\ + .order_by('-date') + by_month = rescues.filter(creation_date__gt=limit)\ + .extra({'date':"date_trunc('month', creation_date)"}) + self.rescue['by_month'] = by_month.values('date')\ + .annotate(number=Count('pk'))\ + .order_by('-date') + + self.rescue['by_dpt'] = FileByDepartment.objects\ + .filter(file__file_type=rescue_type, + department__isnull=False)\ + .values('department__label')\ + .annotate(number=Count('file'))\ + .order_by('department__label') + self.rescue['towns'] = FileTown.objects\ + .filter(file__file_type=rescue_type)\ + .values('town__name')\ + .annotate(number=Count('file'))\ + .order_by('-number','town__name')[:10] + + self.rescue['with_associated_operation'] = rescues\ + .filter(operations__isnull=False).count() + + self.rescue['with_associated_operation_percent'] = round( + float(self.rescue['with_associated_operation'])\ + /self.rescue['total_number']*100, 2) + + by_year_operationnal = rescues.filter(operations__isnull=False)\ + .extra({'date':"date_trunc('year', creation_date)"}) + by_year_operationnal = by_year_operationnal.values('date')\ + .annotate(number=Count('pk'))\ + .order_by('-date') + percents, idx = [], 0 + for dct in self.rescue['by_year']: + if idx > len(by_year_operationnal): + break + if by_year_operationnal[idx]['date'] != dct['date'] or\ + not dct['number']: + continue + val = round(float(by_year_operationnal[idx]['number'])/\ + dct['number']*100, 2) + percents.append({'date':dct['date'], 'number':val}) + self.rescue['operational_by_year'] = percents + + self.rescue['surface_by_town'] = FileTown.objects\ + .filter(file__file_type=rescue_type)\ + .values('town__name')\ + .annotate(number=Sum('file__total_surface'))\ + .order_by('-number','town__name')[:10] + self.rescue['surface_by_dpt'] = FileByDepartment.objects\ + .filter(file__file_type=rescue_type, + department__isnull=False)\ + .values('department__label')\ + .annotate(number=Sum('file__total_surface'))\ + .order_by('department__label') diff --git a/archaeological_files/urls.py b/archaeological_files/urls.py new file mode 100644 index 000000000..e32ab8294 --- /dev/null +++ b/archaeological_files/urls.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> + +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +from django.conf.urls.defaults import * + +""" +import forms + +# forms +urlpatterns = patterns('', + url(r'file_search/(?P<step>.+)$', + forms.file_search_wizard, name='file_search'), + url(r'file_creation/(?P<step>.+)$', + forms.file_creation_wizard, name='file_creation'), + url(r'file_modification/(?P<step>.+)$', + forms.file_modification_wizard, name='file_modification'), + url(r'file_closing/(?P<step>.+)$', + forms.file_closing_wizard, name='file_closing'), + url(r'file_deletion/(?P<step>.+)$', + forms.file_deletion_wizard, name='file_deletion'), + url(r'file_administrativeactfile/(?P<step>.+)$', + forms.file_administrativeactfile_wizard, + name='file_administrativeactfile'), + url(r'file_administrativeactfile_modification/(?P<step>.+)$', + forms.file_administrativeactfile_modification_wizard, + name='file_administrativeactfile_modification'), + url(r'file_administrativeactfile_deletion/(?P<step>.+)$', + forms.file_administrativeactfile_deletion_wizard, + name='file_administrativeactfile_deletion'), +) + +urlpatterns += patterns('archaeological_files.views', + url(r'autocomplete-file/$', 'autocomplete_file', + name='autocomplete-file'), + url(r'get-file/(?P<type>.+)?$', 'get_file', + name='get-file'), + url(r'get-file-full/(?P<type>.+)?$', 'get_file', + name='get-file-full', kwargs={'full':True}), + url(r'get-administrativeactfile/(?P<type>.+)?$', + 'get_administrativeactfile', name='get-administrativeactfile'), + url(r'show-file/(?P<pk>.+)?/(?P<type>.+)?$', 'show_file', + name='show-file'), + url(r'show-historized-file/(?P<pk>.+)?/(?P<date>.+)?$', + 'show_file', name='show-historized-file'), + url(r'revert-file/(?P<pk>.+)/(?P<date>.+)$', + 'revert_file', name='revert-file'), +) +""" diff --git a/archaeological_files/views.py b/archaeological_files/views.py new file mode 100644 index 000000000..02332b629 --- /dev/null +++ b/archaeological_files/views.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2010-2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> + +# 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 <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +import json + +from django.db.models import Q +from django.http import HttpResponse +from django.shortcuts import render_to_response + +from ishtar_common.views import get_item, show_item, revert_item +import models + +def autocomplete_file(request): + person_types = request.user.ishtaruser.person.person_type + if (not request.user.has_perm('ishtar_common.view_file', models.File) and \ + not request.user.has_perm('ishtar_common.view_own_file', models.File) + and not person_types.rights.filter(wizard__url_name='file_search' + ).count()): + return HttpResponse(mimetype='text/plain') + if not request.GET.get('term'): + return HttpResponse(mimetype='text/plain') + q = request.GET.get('term') + query = Q() + for q in q.split(' '): + extra = Q(internal_reference__icontains=q) | \ + Q(towns__name__icontains=q) + try: + value = int(q) + extra = extra | Q(year=q) | Q(numeric_reference=q) + except ValueError: + pass + query = query & extra + limit = 20 + files = models.File.objects.filter(query)[:limit] + data = json.dumps([{'id':file.pk, 'value':unicode(file)} + for file in files]) + return HttpResponse(data, mimetype='text/plain') + +get_file = get_item(models.File, 'get_file', 'file') +show_file = show_item(models.File, 'file') +revert_file = revert_item(models.File) + +def dashboard_file(request, dct, obj_id=None, *args, **kwargs): + """ + Main dashboard + """ + dct = {'dashboard': models.FileDashboard()} + return render_to_response('dashboard_file.html', dct, + context_instance=RequestContext(request)) + |