diff options
| -rw-r--r-- | archaeological_context_records/models.py | 50 | ||||
| -rw-r--r-- | archaeological_context_records/views.py | 51 | ||||
| -rw-r--r-- | archaeological_files/models.py | 30 | ||||
| -rw-r--r-- | archaeological_files/views.py | 57 | ||||
| -rw-r--r-- | archaeological_finds/models.py | 71 | ||||
| -rw-r--r-- | archaeological_finds/views.py | 83 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 131 | ||||
| -rw-r--r-- | archaeological_operations/views.py | 105 | ||||
| -rw-r--r-- | archaeological_warehouse/models.py | 9 | ||||
| -rw-r--r-- | archaeological_warehouse/views.py | 9 | ||||
| -rw-r--r-- | ishtar_common/models.py | 33 | ||||
| -rw-r--r-- | ishtar_common/templates/blocks/JQueryJqGrid.html | 7 | ||||
| -rw-r--r-- | ishtar_common/urls.py | 2 | ||||
| -rw-r--r-- | ishtar_common/views.py | 120 | ||||
| -rw-r--r-- | ishtar_common/widgets.py | 13 | 
15 files changed, 426 insertions, 345 deletions
| diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index e1cb216a2..625356990 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -135,6 +135,27 @@ class ContextRecord(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):          }      }      IMAGE_PREFIX = 'context_records/' + +    # search parameters +    CONTEXTRECORD_EXTRA_KEYS = { +        'parcel__town': 'parcel__town__pk', +        'operation__year': 'operation__year__contains', +        'operation__code_patriarche': 'operation__code_patriarche', +        'operation__operation_code': 'operation__operation_code', +        'datings__period': 'datings__period__pk', +        'parcel_0': 'operation__parcels__section', +        'parcel_1': 'operation__parcels__parcel_number', +        'parcel_2': 'operation__parcels__public_domain', +        'label': 'label__icontains', +        'archaeological_sites': 'operation__archaeological_sites__pk', +        'cached_label': 'cached_label__icontains', +    } +    RELATION_TYPES_PREFIX = {'ope_relation_types': 'operation__'} +    RELATIVE_SESSION_NAMES = [ +        ('operation', 'operation__pk'), +        ('file', 'operation__associated_file__pk')] + +    # fields      external_id = models.TextField(_(u"External ID"), blank=True, null=True)      auto_external_id = models.BooleanField(          _(u"External ID is set automatically"), default=False) @@ -383,6 +404,11 @@ class RecordRelations(GeneralRecordRelations, models.Model):          "right_record__datings__period": _(u"Periods (right)")      } +    # search parameters +    EXTRA_REQUEST_KEYS = { +        "left_record__operation": "left_record__operation__pk" +    } +      class Meta:          verbose_name = _(u"Record relation")          verbose_name_plural = _(u"Record relations") @@ -396,6 +422,30 @@ class ContextRecordSource(Source):      TABLE_COLS = ['context_record__operation', 'context_record'] + \          Source.TABLE_COLS +    # search parameters +    RELATIVE_SESSION_NAMES = [ +        ('contextrecord', 'context_record__pk'), +        ('operation', 'context_record__operation__pk'), +        ('file', 'context_record__operation__associated_file__pk')] +    BOOL_FIELDS = ['duplicate'] +    EXTRA_REQUEST_KEYS = { +        'title': 'title__icontains', +        'description': 'description__icontains', +        'comment': 'comment__icontains', +        'person': 'authors__person__pk', +        'additional_information': 'additional_information__icontains', +        'context_record__parcel__town': 'context_record__parcel__town__pk', +        'context_record__operation__year': 'context_record__operation__year', +        'context_record__operation__operation_code': +        'context_record__operation__operation_code', +        'context_record__operation__code_patriarche': +        'context_record__operation__code_patriarche', +        'context_record__operation': 'context_record__operation__pk', +        'context_record__datings__period': +            'context_record__datings__period__pk', +        'context_record__unit': 'context_record__unit__pk', +    } +      class Meta:          verbose_name = _(u"Context record documentation")          verbose_name_plural = _(u"Context record documentations") diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index 0ced39b20..8991e4edd 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -35,20 +35,6 @@ import models  show_contextrecord = show_item(models.ContextRecord, 'contextrecord')  revert_contextrecord = revert_item(models.ContextRecord) -contextrecord_extra_keys = { -    'parcel__town': 'parcel__town__pk', -    'operation__year': 'operation__year__contains', -    'operation__code_patriarche': 'operation__code_patriarche', -    'operation__operation_code': 'operation__operation_code', -    'datings__period': 'datings__period__pk', -    'parcel_0': 'operation__parcels__section', -    'parcel_1': 'operation__parcels__parcel_number', -    'parcel_2': 'operation__parcels__public_domain', -    'label': 'label__icontains', -    'archaeological_sites': 'operation__archaeological_sites__pk', -    'cached_label': 'cached_label__icontains', -} -  def autocomplete_contextrecord(request):      if (not request.user.has_perm( @@ -80,16 +66,10 @@ def autocomplete_contextrecord(request):  get_contextrecord = get_item(      models.ContextRecord, -    'get_contextrecord', 'contextrecord', -    relation_types_prefix={'ope_relation_types': 'operation__'}, -    relative_session_names=[ -        ('operation', 'operation__pk'), -        ('file', 'operation__associated_file__pk')], -    extra_request_keys=contextrecord_extra_keys,) +    'get_contextrecord', 'contextrecord')  get_contextrecord_for_ope = get_item(      models.ContextRecord,      'get_contextrecord', 'contextrecord', -    extra_request_keys=contextrecord_extra_keys,      own_table_cols=models.ContextRecord.TABLE_COLS_FOR_OPE)  show_contextrecordsource = show_item(models.ContextRecordSource, @@ -97,36 +77,11 @@ show_contextrecordsource = show_item(models.ContextRecordSource,  get_contextrecordsource = get_item(      models.ContextRecordSource, -    'get_contextrecordsource', 'contextrecordsource', -    relative_session_names=[ -        ('contextrecord', 'context_record__pk'), -        ('operation', 'context_record__operation__pk'), -        ('file', 'context_record__operation__associated_file__pk')], -    bool_fields=['duplicate'], -    extra_request_keys={ -        'title': 'title__icontains', -        'description': 'description__icontains', -        'comment': 'comment__icontains', -        'person': 'authors__person__pk', -        'additional_information': 'additional_information__icontains', -        'context_record__parcel__town': 'context_record__parcel__town__pk', -        'context_record__operation__year': 'context_record__operation__year', -        'context_record__operation__operation_code': -        'context_record__operation__operation_code', -        'context_record__operation__code_patriarche': -        'context_record__operation__code_patriarche', -        'context_record__operation': 'context_record__operation__pk', -        'context_record__datings__period': -            'context_record__datings__period__pk', -        'context_record__unit': 'context_record__unit__pk', -    }) +    'get_contextrecordsource', 'contextrecordsource')  get_contextrecordrelation = get_item(      models.RecordRelations, 'get_contextrecordrelation', -    'contextrecordrelation', -    extra_request_keys={ -        "left_record__operation": "left_record__operation__pk" -    }) +    'contextrecordrelation')  record_search_wizard = SearchWizard.as_view([      ('general-record_search', RecordFormSelection)], diff --git a/archaeological_files/models.py b/archaeological_files/models.py index 3721e4d3d..623eb1dee 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- -# Copyright (C) 2012-2015 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2012-2016 É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 @@ -77,10 +77,34 @@ if settings.COUNTRY == 'fr':  class File(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,             ShortMenuItem, DashboardFormItem): +    SLUG = 'file' +    SHOW_URL = 'show-file'      TABLE_COLS = ['numeric_reference', 'year', 'internal_reference',                    'file_type', 'saisine_type', 'towns', ] -    SHOW_URL = 'show-file' -    SLUG = 'file' + +    # search parameters +    BOOL_FIELDS = ['end_date__isnull'] +    EXTRA_REQUEST_KEYS = { +        'parcel_0': ('parcels__section', +                     'operations__parcels__section'), +        'parcel_1': ('parcels__parcel_number', +                     'operations__parcels__parcel_number'), +        'parcel_2': ('operations__parcels__public_domain', +                     'parcels__public_domain'), +        'end_date': 'end_date__isnull', +        'towns__numero_insee__startswith': +        'towns__numero_insee__startswith', +        'name': 'name__icontains', +        'cached_label': 'cached_label__icontains', +        'comment': 'comment__icontains', +        'permit_reference': 'permit_reference__icontains', +        'general_contractor__attached_to': +            'general_contractor__attached_to__pk', +        'history_creator': 'history_creator__ishtaruser__person__pk', +        'history_modifier': 'history_modifier__ishtaruser__person__pk', +    } + +    # fields      year = models.IntegerField(_(u"Year"),                                 default=lambda: datetime.datetime.now().year)      numeric_reference = models.IntegerField( diff --git a/archaeological_files/views.py b/archaeological_files/views.py index a8053214f..0b05ad37d 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -28,7 +28,6 @@ from django.utils.translation import ugettext_lazy as _  from ishtar_common.views import get_item, show_item, revert_item -from ishtar_common.models import Person  from archaeological_operations.models import Operation  import models @@ -77,28 +76,7 @@ def autocomplete_file(request):                         for file in files])      return HttpResponse(data, mimetype='text/plain') -get_file = get_item( -    models.File, 'get_file', 'file', -    bool_fields=['end_date__isnull'], -    extra_request_keys={ -        'parcel_0': ('parcels__section', -                     'operations__parcels__section'), -        'parcel_1': ('parcels__parcel_number', -                     'operations__parcels__parcel_number'), -        'parcel_2': ('operations__parcels__public_domain', -                     'parcels__public_domain'), -        'end_date': 'end_date__isnull', -        'towns__numero_insee__startswith': -        'towns__numero_insee__startswith', -        'name': 'name__icontains', -        'cached_label': 'cached_label__icontains', -        'comment': 'comment__icontains', -        'permit_reference': 'permit_reference__icontains', -        'general_contractor__attached_to': -            'general_contractor__attached_to__pk', -        'history_creator': 'history_creator__ishtaruser__person__pk', -        'history_modifier': 'history_modifier__ishtaruser__person__pk', -    },) +get_file = get_item(models.File, 'get_file', 'file')  revert_file = revert_item(models.File) @@ -113,38 +91,7 @@ show_file = show_item(models.File, 'file', extra_dct=extra_file_dct)  get_administrativeactfile = get_item(      AdministrativeAct, 'get_administrativeactfile', 'administrativeactfile', -    associated_models=[ -        (models.File, 'associated_file'), -        (Person, 'associated_file__general_contractor')], -    dated_fields=['signature_date__lte', 'signature_date__gte'], -    extra_request_keys={ -        'year': 'signature_date__year', -        'associated_file__towns': 'associated_file__towns__pk', -        'history_creator': 'history_creator__ishtaruser__person__pk', -        'associated_file__operations__code_patriarche': -        'associated_file__operations__code_patriarche', -        'act_type__intented_to': 'act_type__intented_to', -        'act_object': 'act_object__icontains', -        'signature_date_before': 'signature_date__lte', -        'signature_date_after': 'signature_date__gte', -        'associated_file__general_contractor__attached_to': -            'associated_file__general_contractor__attached_to__pk', -        'associated_file__name': 'associated_file__name__icontains', -        'associated_file__towns__numero_insee__startswith': -        'associated_file__towns__numero_insee__startswith', -        'indexed': 'index__isnull', -        'parcel_0': ('operation__parcels__section', -                     'associated_file__parcels__section'), -        'parcel_1': ( -            'operation__parcels__parcel_number', -            'associated_file__parcels__parcel_number'), -        'parcel_2': ('operations__parcels__public_domain', -                     'associated_file__parcels__public_domain'), -        'associated_file__permit_reference': -            'associated_file__permit_reference__icontains'}, -    reversed_bool_fields=['index__isnull'], -    base_request={"associated_file__pk__isnull": False}, -    relative_session_names=[('file', 'associated_file__pk')]) +    base_request={"associated_file__pk__isnull": False})  def dashboard_file(request, *args, **kwargs): diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py index 5581df084..969e9b966 100644 --- a/archaeological_finds/models.py +++ b/archaeological_finds/models.py @@ -327,6 +327,46 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):          'base_finds.discovery_date': _(u"Base find - Discovery date"),      }      ATTRS_EQUIV = {'get_first_base_find': 'base_finds'} + +    # search parameters +    REVERSED_BOOL_FIELDS = ['image__isnull'] +    RELATION_TYPES_PREFIX = { +        'ope_relation_types': +        'base_finds__context_record__operation__'} +    RELATIVE_SESSION_NAMES = [ +        ('contextrecord', 'base_finds__context_record__pk'), +        ('operation', 'base_finds__context_record__operation__pk'), +        ('file', 'base_finds__context_record__operation__associated_file__pk') +    ] +    BASE_REQUEST = {'downstream_treatment__isnull': True} +    EXTRA_KEYS = { +        'base_finds__cache_short_id': +            'base_finds__cache_short_id__icontains', +        'base_finds__cache_complete_id': +            'base_finds__cache_complete_id__icontains', +        'label': +            'label__icontains', +        'base_finds__context_record': +            'base_finds__context_record__pk', +        'base_finds__context_record__parcel__town': +            'base_finds__context_record__parcel__town', +        'base_finds__context_record__operation__year': +            'base_finds__context_record__operation__year__contains', +        'base_finds__context_record__operation': +            'base_finds__context_record__operation__pk', +        'archaeological_sites': +            'base_finds__context_record__operation__archaeological_sites__pk', +        'base_finds__context_record__operation__code_patriarche': +            'base_finds__context_record__operation__code_patriarche', +        'datings__period': 'datings__period__pk', +        'base_finds__find__description': +            'base_finds__find__description__icontains', +        'base_finds__batch': 'base_finds__batch', +        'basket': 'basket', +        'cached_label': 'cached_label__icontains', +        'image': 'image__isnull'} + +    # fields      base_finds = models.ManyToManyField(BaseFind, verbose_name=_(u"Base find"),                                          related_name='find')      external_id = models.TextField(_(u"External ID"), blank=True, null=True) @@ -679,6 +719,31 @@ class FindSource(Source):                    'find__base_finds__context_record', 'find'] + \          Source.TABLE_COLS +    # search parameters +    BOOL_FIELDS = ['duplicate'] +    RELATIVE_SESSION_NAMES = [ +        ('find', 'find__pk'), +        ('contextrecord', 'find__base_finds__context_record__pk'), +        ('operation', 'find__base_finds__context_record__operation__pk'), +        ('file', +         'find__base_finds__context_record__operation__associated_file__pk') +    ] +    EXTRA_REQUEST_KEYS = { +        'title': 'title__icontains', +        'description': 'description__icontains', +        'comment': 'comment__icontains', +        'additional_information': 'additional_information__icontains', +        'person': 'authors__person__pk', +        'find__base_finds__context_record__operation__year': +        'find__base_finds__context_record__operation__year', +        'find__base_finds__context_record__operation__operation_code': +        'find__base_finds__context_record__operation__operation_code', +        'find__base_finds__context_record__operation__code_patriarche': +        'find__base_finds__context_record__operation__code_patriarche', +        'find__datings__period': 'find__datings__period__pk', +        'find__description': 'find__description__icontains', +    } +      class Meta:          verbose_name = _(u"Find documentation")          verbose_name_plural = _(u"Find documentations") @@ -846,6 +911,9 @@ class FindUpstreamTreatments(AbsFindTreatments):                    'treatment__location', 'treatment__container',                    'treatment__person', 'treatment_nb'] +    # search parameters +    EXTRA_REQUEST_KEYS = {'find_id': 'find_id'} +      class Meta:          managed = False          db_table = 'find_uptreatments' @@ -887,6 +955,9 @@ class FindDownstreamTreatments(AbsFindTreatments):                    'treatment__location', 'treatment__container',                    'treatment__person', 'treatment_nb'] +    # search parameters +    EXTRA_REQUEST_KEYS = {'find_id': 'find_id'} +      class Meta:          managed = False          db_table = 'find_downtreatments' diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index d441559cc..89babe9b7 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -40,81 +40,14 @@ from wizards import *  from forms import *  import models -find_extra_keys = { -    'base_finds__cache_short_id': -        'base_finds__cache_short_id__icontains', -    'base_finds__cache_complete_id': -        'base_finds__cache_complete_id__icontains', -    'label': -        'label__icontains', -    'base_finds__context_record': -        'base_finds__context_record__pk', -    'base_finds__context_record__parcel__town': -        'base_finds__context_record__parcel__town', -    'base_finds__context_record__operation__year': -        'base_finds__context_record__operation__year__contains', -    'base_finds__context_record__operation': -        'base_finds__context_record__operation__pk', -    'archaeological_sites': -        'base_finds__context_record__operation__archaeological_sites__pk', -    'base_finds__context_record__operation__code_patriarche': -        'base_finds__context_record__operation__code_patriarche', -    'datings__period': 'datings__period__pk', -    'base_finds__find__description': -        'base_finds__find__description__icontains', -    'base_finds__batch': 'base_finds__batch', -    'basket': 'basket', -    'cached_label': 'cached_label__icontains', -    'image': 'image__isnull'} - -get_find = get_item( -    models.Find, 'get_find', 'find', -    reversed_bool_fields=['image__isnull'], -    relation_types_prefix={ -        'ope_relation_types': -        'base_finds__context_record__operation__'}, -    relative_session_names=[ -        ('contextrecord', 'base_finds__context_record__pk'), -        ('operation', 'base_finds__context_record__operation__pk'), -        ('file', 'base_finds__context_record__operation__associated_file__pk') -    ], -    base_request={'downstream_treatment__isnull': True}, -    extra_request_keys=find_extra_keys.copy()) - -get_find_for_ope = get_item( -    models.Find, 'get_find', 'find', -    reversed_bool_fields=['image__isnull'], -    base_request={'downstream_treatment__isnull': True}, -    extra_request_keys=find_extra_keys.copy(), -    own_table_cols=models.Find.TABLE_COLS_FOR_OPE) +get_find = get_item(models.Find, 'get_find', 'find') + +get_find_for_ope = get_item(models.Find, 'get_find', 'find', +                            own_table_cols=models.Find.TABLE_COLS_FOR_OPE)  show_findsource = show_item(models.FindSource, 'findsource') -get_findsource = get_item( -    models.FindSource, 'get_findsource', 'findsource', -    bool_fields=['duplicate'], -    relative_session_names=[ -        ('find', 'find__pk'), -        ('contextrecord', 'find__base_finds__context_record__pk'), -        ('operation', 'find__base_finds__context_record__operation__pk'), -        ('file', -         'find__base_finds__context_record__operation__associated_file__pk') -    ], -    extra_request_keys={ -        'title': 'title__icontains', -        'description': 'description__icontains', -        'comment': 'comment__icontains', -        'additional_information': 'additional_information__icontains', -        'person': 'authors__person__pk', -        'find__base_finds__context_record__operation__year': -        'find__base_finds__context_record__operation__year', -        'find__base_finds__context_record__operation__operation_code': -        'find__base_finds__context_record__operation__operation_code', -        'find__base_finds__context_record__operation__code_patriarche': -        'find__base_finds__context_record__operation__code_patriarche', -        'find__datings__period': 'find__datings__period__pk', -        'find__description': 'find__description__icontains', -    }) +get_findsource = get_item(models.FindSource, 'get_findsource', 'findsource')  show_find = show_item(models.Find, 'find')  revert_find = revert_item(models.Find) @@ -343,13 +276,11 @@ class DeleteFindBasketView(IshtarMixin, LoginRequiredMixin, FormView):          return HttpResponseRedirect(self.get_success_url())  get_upstreamtreatment = get_item( -    models.FindUpstreamTreatments, 'get_upstreamtreatment', 'uptreatment', -    extra_request_keys={'find_id': 'find_id'}) +    models.FindUpstreamTreatments, 'get_upstreamtreatment', 'uptreatment')  get_downstreamtreatment = get_item(      models.FindDownstreamTreatments, 'get_downstreamtreatment', -    'downtreatment', -    extra_request_keys={'find_id': 'find_id'}) +    'downtreatment')  treatment_creation_wizard = TreatmentWizard.as_view([      ('basetreatment-treatment_creation', BaseTreatmentForm), diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index d64936c90..ce804765d 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -177,10 +177,56 @@ class Operation(ClosedItem, BaseHistorizedItem, ImageModel, OwnPerms,      QUALITY_DICT = dict(QUALITY)      SHOW_URL = 'show-operation'      TABLE_COLS = ['year_index', 'operation_type', 'remains', 'towns', -                  'start_date', 'excavation_end_date'] -    TABLE_COLS.insert(4, 'associated_file_short_label') +                  'associated_file_short_label', 'start_date', +                  'excavation_end_date']      IMAGE_PREFIX = 'operations/'      SLUG = 'operation' + +    # search parameters +    BOOL_FIELDS = ['end_date__isnull', 'virtual_operation', +                   'documentation_received', 'finds_received'] +    DATED_FIELDS = [ +        'start_date__lte', 'start_date__gte', 'excavation_end_date__lte', +        'excavation_end_date__gte', 'documentation_deadline__lte', +        'documentation_deadline__gte', 'finds_deadline__lte', +        'finds_deadline__gte'] +    RELATIVE_SESSION_NAMES = [('file', 'associated_file__pk')] +    EXTRA_REQUEST_KEYS = { +        'common_name': 'common_name__icontains', +        'cached_label': 'cached_label__icontains', +        'comment': 'comment__icontains', +        'scientific_documentation_comment': +        'scientific_documentation_comment__icontains', +        'abstract': 'abstract__icontains', +        'end_date': 'end_date__isnull', +        'year_index': ('year', 'operation_code'), +        'start_before': 'start_date__lte', +        'start_after': 'start_date__gte', +        'end_before': 'excavation_end_date__lte', +        'end_after': 'excavation_end_date__gte', +        'towns__numero_insee__startswith': +        'towns__numero_insee__startswith', +        'parcel_0': ('parcels__section', +                     'associated_file__parcels__section'), +        'parcel_1': ( +            'parcels__parcel_number', +            'associated_file__parcels__parcel_number'), +        'parcel_2': ( +            'parcels__public_domain', +            'associated_file__parcels__public_domain'), +        'history_creator': +        'history_creator__ishtaruser__person__pk', +        'history_modifier': +        'history_modifier__ishtaruser__person__pk', +        'archaeological_sites': +        'archaeological_sites__pk', +        'documentation_deadline_before': 'documentation_deadline__lte', +        'documentation_deadline_after': 'documentation_deadline__gte', +        'finds_deadline_before': 'finds_deadline__lte', +        'finds_deadline_after': 'finds_deadline__gte', +    } + +    # fields definition      creation_date = models.DateField(_(u"Creation date"),                                       default=datetime.date.today)      end_date = models.DateField(_(u"Closing date"), null=True, blank=True) @@ -760,6 +806,31 @@ class OperationByDepartment(models.Model):  class OperationSource(Source): +    SHOW_URL = 'show-operationsource' +    MODIFY_URL = 'operation_source_modify' +    TABLE_COLS = ['operation.year', 'operation.operation_code', 'index'] + \ +        Source.TABLE_COLS + +    # search parameters +    BOOL_FIELDS = ['duplicate'] +    EXTRA_REQUEST_KEYS = { +        'title': 'title__icontains', +        'description': 'description__icontains', +        'comment': 'comment__icontains', +        'additional_information': 'additional_information__icontains', +        'person': 'authors__person__pk', +        'operation__towns': 'operation__towns__pk', +        'operation__operation_code': 'operation__operation_code', +        'operation__code_patriarche': 'operation__code_patriarche', +        'operation__operation_type': 'operation__operation_type__pk', +        'operation__year': 'operation__year'} + +    # fields +    operation = models.ForeignKey(Operation, verbose_name=_(u"Operation"), +                                  related_name="source") +    index = models.IntegerField(verbose_name=_(u"Index"), blank=True, +                                null=True) +      class Meta:          verbose_name = _(u"Operation documentation")          verbose_name_plural = _(u"Operation documentations") @@ -775,14 +846,6 @@ class OperationSource(Source):              ("delete_own_operationsource",               ugettext(u"Can delete own Operation source")),          ) -    operation = models.ForeignKey(Operation, verbose_name=_(u"Operation"), -                                  related_name="source") -    index = models.IntegerField(verbose_name=_(u"Index"), blank=True, -                                null=True) -    TABLE_COLS = ['operation.year', 'operation.operation_code', 'index'] + \ -        Source.TABLE_COLS -    SHOW_URL = 'show-operationsource' -    MODIFY_URL = 'operation_source_modify'      @property      def owner(self): @@ -823,6 +886,54 @@ class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter):          TABLE_COLS.append('departments_label')          TABLE_COLS_FILE.append('departments_label')          TABLE_COLS_OPE.append('departments_label') + +    # search parameters +    DATED_FIELDS = ['signature_date__lte', 'signature_date__gte'] +    ASSOCIATED_MODELS = [ +        (models.File, 'associated_file'), +        (Person, 'associated_file__general_contractor')] +    EXTRA_REQUEST_KEYS = { +        'act_object': 'act_object__icontains', +        'act_type__intented_to': 'act_type__intented_to', +        'associated_file__general_contractor__attached_to': +            'associated_file__general_contractor__attached_to__pk', +        'associated_file__name': 'associated_file__name__icontains', +        'associated_file__operations__code_patriarche': +        'associated_file__operations__code_patriarche', +        'associated_file__permit_reference': +            'associated_file__permit_reference__icontains', +        'associated_file__towns': 'associated_file__towns__pk', +        'associated_file__towns__numero_insee__startswith': +        'associated_file__towns__numero_insee__startswith', +        'indexed': 'index__isnull', +        'history_creator': +        'history_creator__ishtaruser__person__pk', +        'history_modifier': +        'history_modifier__ishtaruser__person__pk', +        'operation__code_patriarche': 'operation__code_patriarche', +        'operation__towns': 'operation__towns__pk', +        'operation__towns__numero_insee__startswith': +        'operation__towns__numero_insee__startswith', +        'parcel_0': ('associated_file__parcels__section', +                     'operation__parcels__section', +                     'operation__associated_file__parcels__section'), +        'parcel_1': ( +            'associated_file__parcels__parcel_number' +            'operation__parcels__parcel_number', +            'operation__associated_file__parcels__parcel_number'), +        'parcel_2': ( +            'associated_file__parcels__public_domain', +            'operation__parcels__public_domain', +            'operation__associated_file__parcels__public_domain'), +        'signature_date_before': 'signature_date__lte', +        'signature_date_after': 'signature_date__gte', +        'year': 'signature_date__year', +    } +    REVERSED_BOOL_FIELDS = ['index__isnull'], +    RELATIVE_SESSION_NAMES = [('operation', 'operation__pk'), +                              ('file', 'associated_file__pk')] + +    # fields      act_type = models.ForeignKey(ActType, verbose_name=_(u"Act type"))      in_charge = models.ForeignKey(          Person, blank=True, null=True, diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index ae82e9e89..18d57e617 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -136,112 +136,21 @@ def get_available_operation_code(request, year=None):                         models.Operation.get_available_operation_code(year)})      return HttpResponse(data, mimetype='text/plain') -get_operation = get_item( -    models.Operation, 'get_operation', 'operation', -    bool_fields=['end_date__isnull', 'virtual_operation', -                 'documentation_received', 'finds_received'], -    dated_fields=['start_date__lte', 'start_date__gte', -                  'excavation_end_date__lte', 'excavation_end_date__gte', -                  'documentation_deadline__lte', 'documentation_deadline__gte', -                  'finds_deadline__lte', 'finds_deadline__gte', -                  ], -    relative_session_names=[('file', 'associated_file__pk')], -    extra_request_keys={ -        'common_name': 'common_name__icontains', -        'cached_label': 'cached_label__icontains', -        'comment': 'comment__icontains', -        'scientific_documentation_comment': -        'scientific_documentation_comment__icontains', -        'abstract': 'abstract__icontains', -        'end_date': 'end_date__isnull', -        'year_index': ('year', 'operation_code'), -        'start_before': 'start_date__lte', -        'start_after': 'start_date__gte', -        'end_before': 'excavation_end_date__lte', -        'end_after': 'excavation_end_date__gte', -        'towns__numero_insee__startswith': -        'towns__numero_insee__startswith', -        'parcel_0': ('parcels__section', -                     'associated_file__parcels__section'), -        'parcel_1': ( -            'parcels__parcel_number', -            'associated_file__parcels__parcel_number'), -        'parcel_2': ( -            'parcels__public_domain', -            'associated_file__parcels__public_domain'), -        'history_creator': -        'history_creator__ishtaruser__person__pk', -        'history_modifier': -        'history_modifier__ishtaruser__person__pk', -        'archaeological_sites': -        'archaeological_sites__pk', -        'documentation_deadline_before': 'documentation_deadline__lte', -        'documentation_deadline_after': 'documentation_deadline__gte', -        'finds_deadline_before': 'finds_deadline__lte', -        'finds_deadline_after': 'finds_deadline__gte', -    }, -) +get_operation = get_item(models.Operation, 'get_operation', 'operation') +  show_operation = show_item(models.Operation, 'operation')  revert_operation = revert_item(models.Operation)  show_operationsource = show_item(models.OperationSource, 'operationsource') -get_operationsource = get_item( -    models.OperationSource, -    'get_operationsource', 'operationsource', -    bool_fields=['duplicate'], -    extra_request_keys={ -        'title': 'title__icontains', -        'description': 'description__icontains', -        'comment': 'comment__icontains', -        'additional_information': 'additional_information__icontains', -        'person': 'authors__person__pk', -        'operation__towns': 'operation__towns__pk', -        'operation__operation_code': 'operation__operation_code', -        'operation__code_patriarche': 'operation__code_patriarche', -        'operation__operation_type': 'operation__operation_type__pk', -        'operation__year': 'operation__year'}) +get_operationsource = get_item(models.OperationSource, 'get_operationsource', +                               'operationsource')  get_administrativeactop = get_item( -    models.AdministrativeAct, -    'get_administrativeactop', 'administrativeactop', -    extra_request_keys={ -        'associated_file__towns': 'associated_file__towns__pk', -        'operation__towns': 'operation__towns__pk', -        'operation__code_patriarche': 'operation__code_patriarche', -        'act_type__intented_to': 'act_type__intented_to', -        'year': 'signature_date__year', -        'act_object': 'act_object__icontains', -        'history_creator': -        'history_creator__ishtaruser__person__pk', -        'history_modifier': -        'history_modifier__ishtaruser__person__pk', -        'operation__towns__numero_insee__startswith': -        'operation__towns__numero_insee__startswith', -        'indexed': 'index__isnull', -        'parcel_0': ('operation__parcels__section', -                     'operation__associated_file__parcels__section'), -        'parcel_1': ( -            'operation__parcels__parcel_number', -            'operation__associated_file__parcels__parcel_number'), -        'parcel_2': ( -            'operation__parcels__public_domain', -            'operation__associated_file__parcels__public_domain'), -    }, -    reversed_bool_fields=['index__isnull'], -    relative_session_names=[('operation', 'operation__pk')]) +    models.AdministrativeAct, 'get_administrativeactop', 'administrativeactop')  get_administrativeact = get_item( -    models.AdministrativeAct, -    'get_administrativeact', 'administrativeact', -    extra_request_keys={'year': 'signature_date__year', -                        'indexed': 'index__isnull', -                        'history_creator': -                        'history_creator__ishtaruser__person__pk', -                        'act_object': 'act_object__icontains', -                        'operation__towns__numero_insee__startswith': -                        'operation__towns__numero_insee__startswith', -                        'operation__towns': 'operation__towns__pk'}, -    reversed_bool_fields=['index__isnull'],) +    models.AdministrativeAct, 'get_administrativeact', 'administrativeact') +  show_administrativeact = show_item(models.AdministrativeAct,                                     'administrativeact') diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 17495bf72..389cc4f5a 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -75,6 +75,15 @@ post_delete.connect(post_save_cache, sender=ContainerType)  class Container(LightHistorizedItem):      TABLE_COLS = ['reference', 'container_type', 'location'] + +    # search parameters +    EXTRA_REQUEST_KEYS = { +        'location': 'location__pk', +        'container_type': 'container_type__pk', +        'reference': 'reference__icontains', +    } + +    # fields      location = models.ForeignKey(Warehouse, verbose_name=_(u"Warehouse"))      container_type = models.ForeignKey(ContainerType,                                         verbose_name=_("Container type")) diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index 486c2a1e0..d8027a9a6 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -29,14 +29,7 @@ from wizards import *  from ishtar_common.forms import FinalForm  from forms import * -get_container = get_item( -    models.Container, -    'get_container', 'container', -    extra_request_keys={ -        'location': 'location__pk', -        'container_type': 'container_type__pk', -        'reference': 'reference__icontains', -    }) +get_container = get_item(models.Container, 'get_container', 'container')  new_warehouse = new_item(models.Warehouse, WarehouseForm)  new_container = new_item(models.Container, ContainerForm) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index ba3d51172..17df621db 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2253,6 +2253,14 @@ pre_delete.connect(pre_delete_import, sender=Import)  class Organization(Address, Merge, OwnPerms, ValueGetter):      TABLE_COLS = ('name', 'organization_type', 'town')      SHOW_URL = 'show-organization' + +    # search parameters +    EXTRA_REQUEST_KEYS = { +        'name': 'name__icontains', +        'organization_type': 'organization_type__pk__in', +    } + +    # fields      name = models.CharField(_(u"Name"), max_length=500)      organization_type = models.ForeignKey(OrganizationType,                                            verbose_name=_(u"Type")) @@ -2336,6 +2344,18 @@ class Person(Address, Merge, OwnPerms, ValueGetter):                    'attached_to', 'town')      SHOW_URL = 'show-person'      MODIFY_URL = 'person_modify' + +    # search parameters +    REVERSED_BOOL_FIELDS = ['ishtaruser__isnull'] +    EXTRA_REQUEST_KEYS = { +        'name': ['name__icontains', 'raw_name__icontains'], +        'surname': ['surname__icontains', 'raw_name__icontains'], +        'attached_to': 'attached_to__pk', +        'person_types': 'person_types__pk__in', +        'ishtaruser__isnull': 'ishtaruser__isnull' +    } + +    # fields      old_title = models.CharField(_(u"Title"), max_length=100, choices=TYPE,                                   blank=True, null=True)      title = models.ForeignKey(TitleType, verbose_name=_(u"Title"), @@ -2527,6 +2547,19 @@ class IshtarUser(User):      TABLE_COLS = ('username', 'person__name', 'person__surname',                    'person__email', 'person__person_types_list',                    'person__attached_to') + +    # search parameters +    EXTRA_REQUEST_KEYS = { +        'username': ['username__icontains'], +        'name': ['person__name__icontains', 'person__raw_name__icontains'], +        'surname': ['person__surname__icontains', +                    'person__raw_name__icontains'], +        'email': ['person__email'], +        'attached_to': 'person__attached_to__pk', +        'person_types': 'person__person_types__pk__in', +    } + +    # fields      person = models.ForeignKey(Person, verbose_name=_(u"Person"), unique=True,                                 related_name='ishtaruser')      advanced_shortcut_menu = models.BooleanField( diff --git a/ishtar_common/templates/blocks/JQueryJqGrid.html b/ishtar_common/templates/blocks/JQueryJqGrid.html index 5972208ee..faa2d9e93 100644 --- a/ishtar_common/templates/blocks/JQueryJqGrid.html +++ b/ishtar_common/templates/blocks/JQueryJqGrid.html @@ -13,9 +13,12 @@  <div id='foot_{{name}}' class='gridfooter'> -{% if source_full %} +{% if source_full or extra_sources %}  <a class='badge {{sname}}-csv' href='{{source}}csv' target='_blank' title="{% trans 'Export as CSV' %}">{% trans "CSV" %}</a> -<a class='badge {{sname}}-csv-full' href='{{source_full}}csv' target='_blank' title="{% trans 'Export as CSV - full' %}">{% trans "CSV full" %}</a> +{% if source_full %}<a class='badge {{sname}}-csv-full' href='{{source_full}}csv' target='_blank' title="{% trans 'Export as CSV - full' %}">{% trans "CSV full" %}</a>{% endif %} +{% for slug, name, extra_source in extra_sources %} +<a class='badge {{slug}}-csv-full' href='{{extra_source}}csv' target='_blank' title="{% trans 'Export as CSV - ' %}{{name}}">{{name}}</a> +{% endfor %}  {% else %}  <a class='{{sname}}-csv' href="{{source}}csv" target="_blank" title="{% trans 'Export as CSV' %}">{% trans "CSV" %}</a>  {% endif %} {{encoding}} diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 22a09a052..edd1ebe75 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -135,6 +135,8 @@ urlpatterns += patterns(      url(r'pin/(?P<item_type>[a-z-]+)/(?P<pk>\d+)/$', 'update_current_item',          name='pin'),      url(r'unpin/(?P<item_type>[a-z-]+)/$', 'unpin', name='unpin'), +    url(r'get-by-importer/(?P<slug>[a-z-]+)/(?P<type>[a-z-]+)?$', +        'get_by_importer', name='get-by-importer'),      url(r'new-person/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',          'new_person', name='new-person'),      url(r'new-person-noorga/' diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 3406cf7af..4ee8da963 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -527,7 +527,7 @@ HIERARCHIC_FIELDS = ['periods', 'period', 'unit', 'material_types',  def get_item(model, func_name, default_name, extra_request_keys=[],               base_request={}, bool_fields=[], reversed_bool_fields=[], -             dated_fields=[], associated_models=[], relative_session_names={}, +             dated_fields=[], associated_models=[], relative_session_names=[],               specific_perms=[], own_table_cols=None, relation_types_prefix={}):      """      Generic treatment of tables @@ -569,6 +569,43 @@ def get_item(model, func_name, default_name, extra_request_keys=[],              data_type = 'json'          if not allowed:              return HttpResponse(EMPTY, mimetype='text/plain') + +        # get defaults from model +        if not extra_request_keys and hasattr(model, 'EXTRA_REQUEST_KEYS'): +            my_extra_request_keys = copy(model.EXTRA_REQUEST_KEYS) +        else: +            my_extra_request_keys = copy(extra_request_keys) +        if not base_request and hasattr(model, 'BASE_REQUEST'): +            my_base_request = copy(model.BASE_REQUEST) +        else: +            my_base_request = copy(base_request) +        if not bool_fields and hasattr(model, 'BOOL_FIELDS'): +            my_bool_fields = model.BOOL_FIELDS[:] +        else: +            my_bool_fields = bool_fields[:] +        if not reversed_bool_fields and hasattr(model, 'REVERSED_BOOL_FIELDS'): +            my_reversed_bool_fields = model.REVERSED_BOOL_FIELDS[:] +        else: +            my_reversed_bool_fields = reversed_bool_fields[:] +        if not dated_fields and hasattr(model, 'DATED_FIELDS'): +            my_dated_fields = model.DATED_FIELDS[:] +        else: +            my_dated_fields = dated_fields[:] +        if not associated_models and hasattr(model, 'ASSOCIATED_MODELS'): +            my_associated_models = model.ASSOCIATED_MODELS[:] +        else: +            my_associated_models = associated_models[:] +        if not relative_session_names and hasattr(model, +                                                  'RELATIVE_SESSION_NAMES'): +            my_relative_session_names = model.RELATIVE_SESSION_NAMES[:] +        else: +            my_relative_session_names = relative_session_names[:] +        if not relation_types_prefix and hasattr(model, +                                                 'RELATION_TYPES_PREFIX'): +            my_relation_types_prefix = copy(model.RELATION_TYPES_PREFIX) +        else: +            my_relation_types_prefix = copy(relation_types_prefix) +          fields = [model._meta.get_field_by_name(k)[0]                    for k in model._meta.get_all_field_names()]          request_keys = dict([ @@ -576,7 +613,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],               field.name + (hasattr(field, 'rel') and field.rel and '__pk'                             or ''))              for field in fields]) -        for associated_model, key in associated_models: +        for associated_model, key in my_associated_models:              associated_fields = [                  associated_model._meta.get_field_by_name(k)[0]                  for k in associated_model._meta.get_all_field_names()] @@ -585,10 +622,10 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                         key + "__" + field.name +                         (hasattr(field, 'rel') and field.rel and '__pk' or ''))                        for field in associated_fields])) -        request_keys.update(extra_request_keys) +        request_keys.update(my_extra_request_keys)          request_items = request.method == 'POST' and request.POST \              or request.GET -        dct = base_request.copy() +        dct = my_base_request          if full == 'shortcut':              dct['cached_label__icontains'] = request.GET.get('term', None)          and_reqs, or_reqs = [], [] @@ -598,15 +635,14 @@ def get_item(model, func_name, default_name, extra_request_keys=[],              return HttpResponse('[]', mimetype='text/plain')          # manage relations types -        my_rtypes_prefix = copy(relation_types_prefix) -        if 'relation_types' not in my_rtypes_prefix: -            my_rtypes_prefix['relation_types'] = '' +        if 'relation_types' not in my_relation_types_prefix: +            my_relation_types_prefix['relation_types'] = ''          relation_types = {} -        for rtype_key in my_rtypes_prefix: -            relation_types[my_rtypes_prefix[rtype_key]] = set() +        for rtype_key in my_relation_types_prefix: +            relation_types[my_relation_types_prefix[rtype_key]] = set()              for k in request_items:                  if k.startswith(rtype_key): -                    relation_types[my_rtypes_prefix[rtype_key]].add( +                    relation_types[my_relation_types_prefix[rtype_key]].add(                          request_items[k])                      continue @@ -637,7 +673,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                      dct = {"pk": request.session[default_name]}              elif dct == base_request:                  # a parent item may be selected in the default menu -                for name, key in relative_session_names: +                for name, key in my_relative_session_names:                      if name in request.session and request.session[name]:                          dct.update({key: request.session[name]})                          break @@ -646,13 +682,13 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                  dct = request.session[func_name]          else:              request.session[func_name] = dct -        for k in (list(bool_fields) + list(reversed_bool_fields)): +        for k in (list(my_bool_fields) + list(my_reversed_bool_fields)):              if k in dct:                  if dct[k] == u"1":                      dct.pop(k)                  else:                      dct[k] = dct[k] == u"2" and True or False -                    if k in reversed_bool_fields: +                    if k in my_reversed_bool_fields:                          dct[k] = not dct[k]                      # check also for empty value with image field                      field_name = k.split('__')[0] @@ -668,7 +704,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                                  dct[k.split('__')[0] + '__regex'] = '.{1}.*'                      except FieldDoesNotExist:                          pass -        for k in dated_fields: +        for k in my_dated_fields:              if k in dct:                  if not dct[k]:                      dct.pop(k) @@ -1001,6 +1037,26 @@ def get_item(model, func_name, default_name, extra_request_keys=[],      return func +def get_by_importer(request, slug, data_type='json', full=False, +                    force_own=False, **dct): +    q = models.ImporterType.objects.filter(slug=slug) +    if not q.count(): +        res = '' +        if data_type == "json": +            res = '{}' +        return HttpResponse(res, mimetype='text/plain') +    imp = q.all()[0].get_importer_class() +    cols = [] +    for formater in imp.LINE_FORMAT: +        if not formater: +            continue +        cols.append(formater.field_name) +    obj_name = imp.OBJECT_CLS.__name__.lower() +    return get_item( +        imp.OBJECT_CLS, 'get_' + obj_name, obj_name, own_table_cols=cols +    )(request, data_type, full, force_own, **dct) + +  def show_item(model, name, extra_dct=None):      def func(request, pk, **dct):          try: @@ -1203,40 +1259,14 @@ new_person = new_item(models.Person, forms.PersonForm)  new_person_noorga = new_item(models.Person, forms.NoOrgaPersonForm)  new_organization = new_item(models.Organization, forms.OrganizationForm)  show_organization = show_item(models.Organization, 'organization') -get_organization = get_item( -    models.Organization, -    'get_organization', 'organization', -    extra_request_keys={ -        'name': 'name__icontains', -        'organization_type': 'organization_type__pk__in', -    }) +get_organization = get_item(models.Organization, 'get_organization', +                            'organization')  new_author = new_item(models.Author, forms.AuthorForm)  show_person = show_item(models.Person, 'person') -get_person = get_item( -    models.Person, -    'get_person', 'person', -    reversed_bool_fields=['ishtaruser__isnull'], -    extra_request_keys={ -        'name': ['name__icontains', 'raw_name__icontains'], -        'surname': ['surname__icontains', 'raw_name__icontains'], -        'attached_to': 'attached_to__pk', -        'person_types': 'person_types__pk__in', -        'ishtaruser__isnull': 'ishtaruser__isnull' -    }) - -get_ishtaruser = get_item( -    models.IshtarUser, -    'get_ishtaruser', 'ishtaruser', -    extra_request_keys={ -        'username': ['username__icontains'], -        'name': ['person__name__icontains', 'person__raw_name__icontains'], -        'surname': ['person__surname__icontains', -                    'person__raw_name__icontains'], -        'email': ['person__email'], -        'attached_to': 'person__attached_to__pk', -        'person_types': 'person__person_types__pk__in', -    }) +get_person = get_item(models.Person, 'get_person', 'person') + +get_ishtaruser = get_item(models.IshtarUser, 'get_ishtaruser', 'ishtaruser')  def action(request, action_slug, obj_id=None, *args, **kwargs): diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 48d1377fa..9e656311b 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -602,6 +602,19 @@ class JQueryJqGrid(forms.RadioSelect):          dct['source'] = unicode(self.source)          if unicode(self.source_full) and unicode(self.source_full) != 'None':              dct['source_full'] = unicode(self.source_full) + +        dct['extra_sources'] = [] +        if self.associated_model: +            model_name = "{}.{}".format( +                self.associated_model.__module__, +                self.associated_model.__name__) +            for imp in models.ImporterType.objects.filter( +                    slug__isnull=False, associated_models=model_name, +                    is_template=True).all(): +                dct['extra_sources'].append(( +                    imp.slug, imp.name, +                    reverse('get-by-importer', args=[imp.slug]))) +          dct.update({'name': name,                      'col_names': col_names,                      'extra_cols': extra_cols, | 
