diff options
35 files changed, 285 insertions, 237 deletions
| diff --git a/archaeological_context_records/migrations/0024_auto_20180530_1900.py b/archaeological_context_records/migrations/0025_auto_20180530_1900.py index 5dac817ff..2e29a4bbd 100644 --- a/archaeological_context_records/migrations/0024_auto_20180530_1900.py +++ b/archaeological_context_records/migrations/0025_auto_20180530_1900.py @@ -10,7 +10,7 @@ class Migration(migrations.Migration):      dependencies = [          ('ishtar_common', '0055_auto_20180530_1900'), -        ('archaeological_context_records', '0023_auto_20180511_1232'), +        ('archaeological_context_records', '0024_auto_20180604_1532'),      ]      operations = [ diff --git a/archaeological_context_records/migrations/0025_migrate_source_and_image.py b/archaeological_context_records/migrations/0026_migrate_source_and_image.py index c190faac2..9f6721128 100644 --- a/archaeological_context_records/migrations/0025_migrate_source_and_image.py +++ b/archaeological_context_records/migrations/0026_migrate_source_and_image.py @@ -21,7 +21,7 @@ def migrate_source_and_image(apps, schema_editor):  class Migration(migrations.Migration):      dependencies = [ -        ('archaeological_context_records', '0024_auto_20180530_1900'), +        ('archaeological_context_records', '0025_auto_20180530_1900'),      ]      operations = [ diff --git a/archaeological_context_records/migrations/0026_auto_20180601_1555.py b/archaeological_context_records/migrations/0027_auto_20180601_1555.py index 44a277279..5a87eefbd 100644 --- a/archaeological_context_records/migrations/0026_auto_20180601_1555.py +++ b/archaeological_context_records/migrations/0027_auto_20180601_1555.py @@ -8,7 +8,7 @@ from django.db import migrations  class Migration(migrations.Migration):      dependencies = [ -        ('archaeological_context_records', '0025_migrate_source_and_image'), +        ('archaeological_context_records', '0026_migrate_source_and_image'),      ]      operations = [ diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource.html b/archaeological_context_records/templates/ishtar/sheet_contextrecordsource.html deleted file mode 100644 index 725c89530..000000000 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "ishtar/sheet_source.html" %} -{% load i18n window_field window_header link_to_window %} - -{% block head_title %}<strong>{% trans "Context record source" %}</strong> - {{item.title}} - {{item.owner}}{% endblock %} - -{% block window_nav %} -{% window_nav item window_id 'show-contextrecordsource' 'record_source_modify' %} -{% endblock %} - -{% block related %} -{% trans "Related context record" as related_item_label %} -{% field_flex related_item_label item.owner '' item.owner|link_to_window %} -{% endblock %} diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html b/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html deleted file mode 100644 index c03b80a53..000000000 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_pdf.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "ishtar/sheet_contextrecordsource.html" %} -{% block header %} -{% endblock %} -{% block main_head %} -{{ block.super }} -<div id="pdfheader"> -Ishtar – {{APP_NAME}} – {{item}} -</div> -{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -</body> -</html> -{%endblock%} diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_window.html b/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_window.html deleted file mode 100644 index 21dd20758..000000000 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecordsource_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "ishtar/sheet_contextrecordsource.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/archaeological_context_records/urls.py b/archaeological_context_records/urls.py index 5610150f1..c05cff87e 100644 --- a/archaeological_context_records/urls.py +++ b/archaeological_context_records/urls.py @@ -19,8 +19,8 @@  from django.conf.urls import url +from ishtar_common.utils import check_rights  from archaeological_context_records import models -from ishtar_common.wizards import check_rights  from archaeological_context_records import views  # be careful: each check_rights must be relevant with ishtar_menu diff --git a/archaeological_files/urls.py b/archaeological_files/urls.py index f00d618d6..9823cf924 100644 --- a/archaeological_files/urls.py +++ b/archaeological_files/urls.py @@ -19,7 +19,7 @@  from django.conf.urls import url -from ishtar_common.wizards import check_rights +from ishtar_common.utils import check_rights  from archaeological_files import views  from archaeological_operations.views import administrativeactfile_document diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 72e4d8607..a217eb079 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -528,6 +528,7 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):              c.execute(sql, args)          Find.cached_label_bulk_update(**kwargs) +  post_save.connect(post_save_point, sender=BaseFind) diff --git a/archaeological_finds/templates/ishtar/sheet_findsource.html b/archaeological_finds/templates/ishtar/sheet_findsource.html deleted file mode 100644 index a3825173f..000000000 --- a/archaeological_finds/templates/ishtar/sheet_findsource.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "ishtar/sheet_source.html" %} -{% load i18n window_field window_header link_to_window %} - -{% block head_title %}<strong>{% trans "Find source" %}</strong> - {{item.title}} - {{item.owner}}{% endblock %} - -{% block window_nav %} -{% window_nav item window_id 'show-findsource' 'find_source_modify' %} -{% endblock %} - -{% block related %} -{% trans "Related find" as related_item_label %} -{% field_flex related_item_label item.owner '' item.owner|link_to_window %} -{% endblock %} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource.html b/archaeological_finds/templates/ishtar/sheet_treatmentfilesource.html deleted file mode 100644 index 17cc14b5b..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "ishtar/sheet_source.html" %} -{% load i18n window_field window_header link_to_window %} - -{% block head_title %}{% trans "Treatment request source" %}{% endblock %} - -{% block window_nav %} -{% window_nav item window_id 'show-treatmentfilesource' 'treatmentfile_source_modify' %} -{% endblock %} - -{% block related %} -{% trans "Related treatment request" as related_item_label %} -{% field related_item_label item.owner '' item.owner|link_to_window %} -{% endblock %} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html deleted file mode 100644 index 2ef4d63b5..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_pdf.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "ishtar/sheet_treatmentfilesource.html" %} -{% block header %} -{% endblock %} -{% block main_head %} -{{ block.super }} -<div id="pdfheader"> -Ishtar – {{APP_NAME}} – {{item}} -</div> -{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -</body> -</html> -{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_window.html b/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_window.html deleted file mode 100644 index 4ebf9c02a..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentfilesource_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "ishtar/sheet_treatmentfilesource.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentsource.html b/archaeological_finds/templates/ishtar/sheet_treatmentsource.html deleted file mode 100644 index 70e69c704..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentsource.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "ishtar/sheet_source.html" %} -{% load i18n window_field window_header link_to_window %} - -{% block head_title %}{% trans "Treatment source" %}{% endblock %} - -{% block window_nav %} -{% window_nav item window_id 'show-treatmentsource' 'treatment_source_modify' %} -{% endblock %} - -{% block related %} -{% trans "Related treatment" as related_item_label %} -{% field related_item_label item.owner '' item.owner|link_to_window %} -{% endblock %} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html b/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html deleted file mode 100644 index 4b7218a14..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentsource_pdf.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "ishtar/sheet_treatmentsource.html" %} -{% block header %} -{% endblock %} -{% block main_head %} -{{ block.super }} -<div id="pdfheader"> -Ishtar – {{APP_NAME}} – {{item}} -</div> -{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -</body> -</html> -{%endblock%} diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentsource_window.html b/archaeological_finds/templates/ishtar/sheet_treatmentsource_window.html deleted file mode 100644 index 2af5ff708..000000000 --- a/archaeological_finds/templates/ishtar/sheet_treatmentsource_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "ishtar/sheet_treatmentsource.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index bd466a1af..ca7f10296 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -19,7 +19,7 @@  from django.conf.urls import url -from ishtar_common.wizards import check_rights +from ishtar_common.utils import check_rights  from archaeological_finds import views  from archaeological_operations.views import administrativeactfile_document diff --git a/archaeological_operations/templates/ishtar/sheet_operationsource.html b/archaeological_operations/templates/ishtar/sheet_operationsource.html deleted file mode 100644 index 91cb483f0..000000000 --- a/archaeological_operations/templates/ishtar/sheet_operationsource.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "ishtar/sheet_source.html" %} -{% load i18n window_field window_header link_to_window %} - -{% block head_title %}<strong>{% trans "Operation source" %}</strong> - {{item.title}} - {{item.owner}}{% endblock %} - -{% block window_nav %} -{% window_nav item window_id 'show-operationsource' 'operation_source_modify' %} -{% endblock %} - -{% block related %} -{% trans "Related operation" as related_item_label %} -{% field_flex related_item_label item.owner '' item.owner|link_to_window %} -{% endblock %} diff --git a/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html b/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html deleted file mode 100644 index 68eb7aa2d..000000000 --- a/archaeological_operations/templates/ishtar/sheet_operationsource_pdf.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "ishtar/sheet_operationsource.html" %} -{% block header %} -{% endblock %} -{% block main_head %} -{{ block.super }} -<div id="pdfheader"> -Ishtar – {{APP_NAME}} – {{item}} -</div> -{% endblock %} -{%block head_sheet%}{%endblock%} -{%block main_foot%} -</body> -</html> -{%endblock%} diff --git a/archaeological_operations/templates/ishtar/sheet_operationsource_window.html b/archaeological_operations/templates/ishtar/sheet_operationsource_window.html deleted file mode 100644 index 8cd2c7fa1..000000000 --- a/archaeological_operations/templates/ishtar/sheet_operationsource_window.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends "ishtar/sheet_operationsource.html" %} -{% block main_head %}{%endblock%} -{% block main_foot %}{%endblock%} diff --git a/archaeological_operations/urls.py b/archaeological_operations/urls.py index 6b9a980b4..759bcc88d 100644 --- a/archaeological_operations/urls.py +++ b/archaeological_operations/urls.py @@ -19,7 +19,7 @@  from django.conf.urls import url -from ishtar_common.wizards import check_rights +from ishtar_common.utils import check_rights  from archaeological_operations import views  from archaeological_operations import models diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 97824843f..5c5a3e89b 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -49,9 +49,9 @@ from archaeological_operations.wizards import has_associated_file, \  from ishtar_common.forms import ClosingDateFormSelection, FinalForm, \      FinalDeleteForm  from ishtar_common.models import get_current_profile, IshtarSiteProfile -from ishtar_common.utils import put_session_message +from ishtar_common.utils import put_session_message, check_rights_condition  from ishtar_common.views import get_item, show_item, revert_item, new_item -from ishtar_common.wizards import SearchWizard, check_rights_condition +from ishtar_common.wizards import SearchWizard  def autocomplete_patriarche(request): diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py index f4cd413ac..26fe4698e 100644 --- a/archaeological_warehouse/urls.py +++ b/archaeological_warehouse/urls.py @@ -19,9 +19,9 @@  from django.conf.urls import url -from ishtar_common.wizards import check_rights -from archaeological_warehouse import views +from ishtar_common.utils import check_rights +from archaeological_warehouse import views  from archaeological_warehouse import models  # be careful: each check_rights must be relevant with ishtar_menu @@ -82,4 +82,4 @@ urlpatterns = [          name='container_deletion'),      url(r'container-modify/(?P<pk>.+)/$',          views.container_modify, name='container_modify'), -]
\ No newline at end of file +] diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 854fe2a71..0473d19b6 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -1052,27 +1052,35 @@ def get_image_help():                'height': settings.IMAGE_MAX_SIZE[1]} -###################### -# Sources management # -###################### -class SourceForm(CustomForm, ManageOldType): +####################### +# Document management # +####################### + + +class DocumentForm(CustomForm, ManageOldType):      form_label = _(u"Documentation informations") -    form_admin_name = _("Source - General") +    form_admin_name = _("Document - General")      file_upload = True      associated_models = {'source_type': models.SourceType} -    title = forms.CharField(label=_(u"Title"), +    title = forms.CharField(label=_(u"Title"), required=False,                              validators=[validators.MaxLengthValidator(200)]) -    source_type = forms.ChoiceField(label=_(u"Source type"), choices=[]) +    source_type = forms.ChoiceField(label=_(u"Source type"), choices=[], +                                    required=False) +    image = forms.ImageField( +        label=_(u"Image"), help_text=mark_safe(get_image_help()), +        max_length=255, required=False, widget=widgets.ImageFileInput()) +    associated_file = forms.FileField( +        label=_(u"File"), max_length=255, required=False) +    associated_url = forms.URLField( +        max_length=1000, required=False, +        label=_(u"Numerical ressource (web address)"))      reference = forms.CharField(          label=_(u"Reference"),          validators=[validators.MaxLengthValidator(100)], required=False)      internal_reference = forms.CharField(          label=_(u"Internal reference"),          validators=[validators.MaxLengthValidator(100)], required=False) -    associated_url = forms.URLField( -        max_length=1000, required=False, -        label=_(u"Numerical ressource (web address)"))      receipt_date = forms.DateField(label=_(u"Receipt date"), required=False,                                     widget=DatePicker)      creation_date = forms.DateField(label=_(u"Creation date"), required=False, @@ -1089,16 +1097,24 @@ class SourceForm(CustomForm, ManageOldType):          required=False)      duplicate = forms.BooleanField(label=_(u"Has a duplicate"),                                     required=False) -    image = forms.ImageField( -        label=_(u"Image"), help_text=mark_safe(get_image_help()), -        max_length=255, required=False, widget=widgets.ImageFileInput())      TYPES = [          FieldType('source_type', models.SourceType),      ] +    def clean(self): +        cleaned_data = self.cleaned_data +        if not cleaned_data.get('title', None) and \ +                not cleaned_data.get('image', None) and \ +                not cleaned_data.get('associated_file', None) and \ +                not cleaned_data.get('associated_url', None): +            raise forms.ValidationError(_(u"You should at least fill one of " +                                          u"this field: title, url, image or " +                                          u"file.")) +        return cleaned_data + -class SourceSelect(TableSelect): +class DocumentSelect(TableSelect):      search_vector = forms.CharField(label=_(u"Full text search"),                                      widget=widgets.SearchWidget)      authors = forms.IntegerField( @@ -1118,10 +1134,30 @@ class SourceSelect(TableSelect):          label=_(u"Additional informations"))      duplicate = forms.NullBooleanField(label=_(u"Has a duplicate")) -    def __init__(self, *args, **kwargs): -        super(SourceSelect, self).__init__(*args, **kwargs) -        self.fields['source_type'].choices = models.SourceType.get_types() -        self.fields['source_type'].help_text = models.SourceType.get_help() +    TYPES = [ +        FieldType('source_type', models.SourceType), +    ] + + +class DocumentFormSelection(forms.Form): +    SEARCH_AND_SELECT = True +    form_label = _(u"Document search") +    associated_models = {'pk': models.Document} +    currents = {'pk': models.Document} + +    pk = forms.IntegerField( +        label="", required=False, +        widget=widgets.DataTable( +            reverse_lazy('get-document'), DocumentSelect, +            models.Document, +        ), +        validators=[models.valid_id(models.Document)]) + +    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 an item.")) +        return cleaned_data  class SourceDeletionForm(FinalForm): diff --git a/ishtar_common/ishtar_menu.py b/ishtar_common/ishtar_menu.py index 6e61ede74..fbd65c103 100644 --- a/ishtar_common/ishtar_menu.py +++ b/ishtar_common/ishtar_menu.py @@ -122,6 +122,21 @@ MENU_SECTIONS = [                  model=models.Import,                  access_controls=['change_import']),          ])), +    (250, SectionItem( +        'document', _(u"Documentation / Images"), +        childs=[ +            MenuItem('document_search', +                     _(u"Search"), +                     model=models.Document, +                     access_controls=['view_document', +                                      'view_own_document']), +            MenuItem('document_creation', +                     _(u"Creation"), +                     model=models.Document, +                     access_controls=['add_document', +                                      'add_own_document']), +        ]) +     )  ]  """  SectionItem( diff --git a/ishtar_common/migrations/0056_auto_20180601_1555.py b/ishtar_common/migrations/0056_auto_20180601_1555.py index fee995df9..71def216e 100644 --- a/ishtar_common/migrations/0056_auto_20180601_1555.py +++ b/ishtar_common/migrations/0056_auto_20180601_1555.py @@ -10,7 +10,7 @@ class Migration(migrations.Migration):      dependencies = [          ('archaeological_warehouse', '0021_auto_20180601_1555'), -        ('archaeological_context_records', '0026_auto_20180601_1555'), +        ('archaeological_context_records', '0027_auto_20180601_1555'),          ('archaeological_finds', '0029_auto_20180601_1555'),          ('archaeological_operations', '0032_auto_20180601_1555'),          ('ishtar_common', '0055_auto_20180530_1900'), diff --git a/ishtar_common/migrations/0057_document_cache_related_label.py b/ishtar_common/migrations/0057_document_cache_related_label.py new file mode 100644 index 000000000..61a8ea329 --- /dev/null +++ b/ishtar_common/migrations/0057_document_cache_related_label.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-06-04 11:52 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0056_auto_20180601_1555'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='document', +            name='cache_related_label', +            field=models.TextField(blank=True, db_index=True, help_text='Cached value - do not edit', null=True, verbose_name='Related'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 76f16eaae..de34a2b9c 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -3093,9 +3093,21 @@ class Document(OwnPerms, ImageModel, FullSearch):          'treatment_files', 'treatments', 'finds', 'context_records',          'operations', 'sites', 'warehouses',      ] - +    SLUG = 'document'      LINK_SPLIT = u"<||>" +    TABLE_COLS = ['title', 'source_type', 'cache_related_label', 'authors', +                  'associated_url'] +    COL_LINK = ['associated_url'] +    BASE_SEARCH_VECTORS = ['title', 'source_type__label', 'external_id', +                           'reference', 'description', 'comment', +                           'additional_information'] +    PARENT_SEARCH_VECTORS = ['authors', ] + +    BOOL_FIELDS = ['duplicate'] + +    CACHED_LABELS = ['cache_related_label'] +      title = models.TextField(_(u"Title"), blank=True, default='')      associated_file = models.FileField(          upload_to=get_image_path, blank=True, null=True, max_length=255) @@ -3137,13 +3149,9 @@ class Document(OwnPerms, ImageModel, FullSearch):      duplicate = models.BooleanField(_(u"Has a duplicate"), default=False)      associated_links = models.TextField(_(u"Symbolic links"), blank=True,                                          null=True) - -    TABLE_COLS = ['title', 'source_type', 'authors', 'associated_url'] -    COL_LINK = ['associated_url'] -    BASE_SEARCH_VECTORS = ['title', 'source_type__label', 'external_id', -                           'reference', 'description', 'comment', -                           'additional_information'] -    PARENT_SEARCH_VECTORS = ['authors', ] +    cache_related_label = models.TextField( +        _(u"Related"), blank=True, null=True, db_index=True, +        help_text=_(u"Cached value - do not edit"))      class Meta:          verbose_name = _(u"Document") @@ -3199,7 +3207,7 @@ class Document(OwnPerms, ImageModel, FullSearch):          for related_model in self.RELATED_MODELS:              q = getattr(self, related_model).all()              if q.count(): -                item = q.all()[0].item +                item = q.all()[0]                  yield item._get_base_image_path()      def _get_base_image_path(self): @@ -3259,7 +3267,7 @@ class Document(OwnPerms, ImageModel, FullSearch):          for related_model in self.RELATED_MODELS:              q = getattr(self, related_model).all()              if q.count(): -                item = q.all()[0].item +                item = q.all()[0]                  base_path = item._get_base_image_path()                  new_path = base_path + u"/" + filename                  if not reference_path: @@ -3295,6 +3303,16 @@ class Document(OwnPerms, ImageModel, FullSearch):                  os.symlink(reference_path, new_path)          return links +    def related_label(self): +        items = [] +        for rel_attr in reversed(self.RELATED_MODELS): +            for item in getattr(self, rel_attr).all(): +                items.append(unicode(item)) +        return u" ; ".join(items) + +    def _generate_cache_related_label(self): +        return self.related_label() +      def save(self, *args, **kwargs):          no_path_change = 'no_path_change' in kwargs \                           and kwargs.pop('no_path_change') @@ -3309,6 +3327,9 @@ class Document(OwnPerms, ImageModel, FullSearch):                  self.save(no_path_change=True) +post_save.connect(cached_label_changed, sender=Document) + +  class Arrondissement(models.Model):      name = models.CharField(u"Nom", max_length=30)      department = models.ForeignKey(Department, verbose_name=u"Département") diff --git a/ishtar_common/templates/ishtar/sheet_source.html b/ishtar_common/templates/ishtar/sheet_document.html index bedcb587e..3d48963a2 100644 --- a/ishtar_common/templates/ishtar/sheet_source.html +++ b/ishtar_common/templates/ishtar/sheet_document.html @@ -1,11 +1,18 @@  {% extends "ishtar/sheet.html" %} -{% load i18n window_field link_to_window %} +{% load i18n window_field window_header link_to_window %} + +{% block head_title %}<strong>{% trans "Document" %}</strong> - {{item.title}}{% endblock %}  {% block content %} -{% block window_nav %}{% endblock %} +{% block window_nav %} +{# {% window_nav item window_id 'show-document' 'document_modify' %} #} +{% window_nav item window_id 'show-document' %} +{% endblock %} + +  {% block general %} -{% if item.image %} +{% if item.images.count %}  <div class="row">      <div class="offset-lg-4 col-lg-4 offset-md-3 col-md-6 offset-sm-1 col-sm-10 col-12">          <div class="card"> @@ -16,10 +23,6 @@  {% endif %}  <div class="row"> -    {% block related %} -    {% trans "Related item" as related_item_label %} -    {% field_flex related_item_label item.owner %} -    {% endblock %}      {% field_flex "Title" item.title %}      {% field_flex "Index" item.index %}      {% field_flex "Source type" item.source_type %} @@ -40,6 +43,19 @@      {% field_flex_full "Authors" item.authors|add_links:'person' %}  </div> -{% endblock %} +{% block related %} +<h2>{% trans "Related items" %}</h2> +{% if item.operations.count %} +{% field_flex_full "Sites" item.sites|add_links %} +{% field_flex_full "Operations" item.operations|add_links %} +{% field_flex_full "Context records" item.context_records|add_links %} +{% field_flex_full "Finds" item.finds|add_links %} +{% field_flex_full "Treatments" item.treatments|add_links %} +{% field_flex_full "Treatment files" item.treatment_files|add_links %} +{% field_flex_full "Warehouses" item.warehouses|add_links %} +{% endif %} +  {% endblock %} +{% endblock %} +{% endblock %} diff --git a/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html b/ishtar_common/templates/ishtar/sheet_document_pdf.html index 7ca3bd3c1..3a40fac44 100644 --- a/archaeological_finds/templates/ishtar/sheet_findsource_pdf.html +++ b/ishtar_common/templates/ishtar/sheet_document_pdf.html @@ -1,4 +1,4 @@ -{% extends "ishtar/sheet_findsource.html" %} +{% extends "ishtar/sheet_document.html" %}  {% block header %}  {% endblock %}  {% block main_head %} diff --git a/archaeological_finds/templates/ishtar/sheet_findsource_window.html b/ishtar_common/templates/ishtar/sheet_document_window.html index b2a2974bf..c739722e7 100644 --- a/archaeological_finds/templates/ishtar/sheet_findsource_window.html +++ b/ishtar_common/templates/ishtar/sheet_document_window.html @@ -1,3 +1,3 @@ -{% extends "ishtar/sheet_findsource.html" %} +{% extends "ishtar/sheet_document.html" %}  {% block main_head %}{%endblock%}  {% block main_foot %}{%endblock%} diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index a64e6ab24..787c72aba 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -24,8 +24,8 @@ from django.views.generic import TemplateView  from menus import Menu -from ishtar_common import views -from ishtar_common.wizards import check_rights +from ishtar_common import views, models +from ishtar_common.utils import check_rights, get_urls_for_model  # be careful: each check_rights must be relevant with ishtar_menu @@ -223,8 +223,27 @@ urlpatterns += [          name='hide-shortcut-menu'),      url(r'show-shortcut-menu/$', views.show_shortcut_menu,          name='show-shortcut-menu'), + +    url(r'document_search/(?P<step>.+)?$', +        check_rights(['view_document', 'view_own_document'])( +            views.document_search_wizard), +        name='document_search'), +    url(r'document_creation/(?P<step>.+)?$', +        check_rights(['add_document', 'add_own_document'])( +            views.NewDocumentFormView.as_view()), +        name='document_creation'), +    url(r'document_modification/(?P<step>.+)?$', +        check_rights(['change_document', 'change_own_document'])( +            views.NewDocumentFormView.as_view()), +        name='document_modification'), +] + +urlpatterns += get_urls_for_model(models.Document, views) + +urlpatterns += [      url(r'(?P<action_slug>' + actions + r')/$', views.action, name='action'),  ] +  """      url(r'operation_source_search/(?P<step>.+)?$',          check_rights(['view_operation', 'view_own_operation'])( diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 6c77563ef..0b5b1bd57 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -30,6 +30,7 @@ import tempfile  from django import forms  from django.conf import settings +from django.conf.urls import url  from django.contrib.contenttypes.models import ContentType  from django.contrib.gis.geos import GEOSGeometry  from django.contrib.sessions.backends.db import SessionStore @@ -56,6 +57,52 @@ class BColors:      UNDERLINE = '\033[4m' +def check_rights(rights=[], redirect_url='/'): +    """ +    Decorator that checks the rights to access the view. +    """ + +    def decorator(view_func): +        def _wrapped_view(request, *args, **kwargs): +            if not rights: +                return view_func(request, *args, **kwargs) +            if hasattr(request.user, 'ishtaruser'): +                if request.user.ishtaruser.has_right('administrator', +                                                     request.session): +                    kwargs['current_right'] = 'administrator' +                    return view_func(request, *args, **kwargs) +                for right in rights: +                    # be careful to put the more permissive rights first +                    # if granted it can allow more +                    if request.user.ishtaruser.has_right(right, +                                                         request.session): +                        kwargs['current_right'] = right +                        return view_func(request, *args, **kwargs) +            put_session_message( +                request.session.session_key, +                _(u"You don't have sufficient permissions to do this action."), +                'warning' +            ) +            return HttpResponseRedirect(redirect_url) +        return _wrapped_view +    return decorator + + +def check_rights_condition(rights): +    """ +    To be used to check in wizard condition_dict +    """ +    def func(self): +        request = self.request +        if request.user.ishtaruser.has_right('administrator', request.session): +            return True +        for right in rights: +            if request.user.ishtaruser.has_right(right, request.session): +                return True +        return False +    return func + +  class MultiValueDict(BaseMultiValueDict):      def get(self, *args, **kwargs):          v = super(MultiValueDict, self).getlist(*args, **kwargs) @@ -703,3 +750,19 @@ def create_default_json_fields(model):              }          ) + +def get_urls_for_model(model, views): +    """ +    Generate get and show url for a model +    """ +    urls = [ +        url(r'show-{}(?:/(?P<pk>.+))?/(?P<type>.+)?$'.format(model.SLUG), +            check_rights(['view_' + model.SLUG, 'view_own_' + model.SLUG])( +                getattr(views, 'show_' + model.SLUG)), +            name="show-" + model.SLUG), +        url(r'get-{}/(?P<type>.+)?$'.format(model.SLUG), +            check_rights(['view_' + model.SLUG, 'view_own_' + model.SLUG])( +                getattr(views, 'get_' + model.SLUG)), +            name="get-" + model.SLUG), +    ] +    return urls diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 5d2b442bf..187712676 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -2483,12 +2483,49 @@ class OrganizationPersonEdit(LoginRequiredMixin, UpdateView):      def get_success_url(self):          return reverse('organization_person_edit', args=[self.object.pk]) + +# documents + +show_document = show_item(models.Document, 'document') +get_document = get_item(models.Document, 'get_document', 'document') + + +document_search_wizard = wizards.SearchWizard.as_view( +    [('selec-document_search', forms.DocumentFormSelection)], +    label=_(u"Document: search"), +    url_name='document_search', +) + + +class NewDocumentFormView(IshtarMixin, LoginRequiredMixin, +                          FormView): +    form_class = forms.DocumentForm +    template_name = 'ishtar/form.html' +    success_url = 'document_search' +  """ +class DocumentSelectMixin(IshtarMixin, LoginRequiredMixin, +                          FormView): +    form_class = forms.PersonMergeFormSelection +    template_name = 'ishtar/form.html' +    redir_url = 'person_manual_merge_items' + +    def form_valid(self, form): +        self.item = form.get_item() +        return super(ManualMergeMixin, self).form_valid(form) + +    def get_success_url(self): +        return reverse(self.redir_url, args=[self.item.pk]) -show_operationsource = show_item(models.OperationSource, 'operationsource') -get_operationsource = get_item(models.OperationSource, 'get_operationsource', -                               'operationsource') +class DocumentSelectView(DocumentSelectMixin, IshtarMixin, LoginRequiredMixin, +                         FormView): +    page_name = _(u"Merge persons") +    current_url = 'person-manual-merge' +    redir_url = 'person_manual_merge_items' +""" + +"""  # operation sources  operation_source_search_wizard = SearchWizard.as_view([ diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index b98c698ac..69f7c4c8e 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -44,57 +44,10 @@ from django.utils.safestring import mark_safe  from ishtar_common import models  from ishtar_common.forms import CustomForm, reverse_lazy -from ishtar_common.utils import get_all_field_names, MultiValueDict, \ -    put_session_message +from ishtar_common.utils import get_all_field_names, MultiValueDict  logger = logging.getLogger(__name__) - -def check_rights(rights=[], redirect_url='/'): -    """ -    Decorator that checks the rights to access the view. -    """ - -    def decorator(view_func): -        def _wrapped_view(request, *args, **kwargs): -            if not rights: -                return view_func(request, *args, **kwargs) -            if hasattr(request.user, 'ishtaruser'): -                if request.user.ishtaruser.has_right('administrator', -                                                     request.session): -                    kwargs['current_right'] = 'administrator' -                    return view_func(request, *args, **kwargs) -                for right in rights: -                    # be careful to put the more permissive rights first -                    # if granted it can allow more -                    if request.user.ishtaruser.has_right(right, -                                                         request.session): -                        kwargs['current_right'] = right -                        return view_func(request, *args, **kwargs) -            put_session_message( -                request.session.session_key, -                _(u"You don't have sufficient permissions to do this action."), -                'warning' -            ) -            return HttpResponseRedirect(redirect_url) -        return _wrapped_view -    return decorator - - -def check_rights_condition(rights): -    """ -    To be used to check in wizard condition_dict -    """ -    def func(self): -        request = self.request -        if request.user.ishtaruser.has_right('administrator', request.session): -            return True -        for right in rights: -            if request.user.ishtaruser.has_right(right, request.session): -                return True -        return False -    return func -  # buggy and unecessary at least for the moment...  """  def _check_right(step, condition=True): | 
