diff options
Diffstat (limited to 'archaeological_finds')
-rw-r--r-- | archaeological_finds/forms.py | 40 | ||||
-rw-r--r-- | archaeological_finds/ishtar_menu.py | 19 | ||||
-rw-r--r-- | archaeological_finds/migrations/0037_auto_20181018_1756.py | 41 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 14 | ||||
-rw-r--r-- | archaeological_finds/templates/ishtar/sheet_findbasket.html | 23 | ||||
-rw-r--r-- | archaeological_finds/urls.py | 19 | ||||
-rw-r--r-- | archaeological_finds/views.py | 54 | ||||
-rw-r--r-- | archaeological_finds/wizards.py | 4 |
8 files changed, 170 insertions, 44 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 610c309d0..370f29cad 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -26,6 +26,7 @@ import logging from django import forms from django.core import validators from django.core.exceptions import PermissionDenied +from django.db.models import Q from django.forms.formsets import formset_factory from django.utils.translation import ugettext_lazy as _ @@ -71,7 +72,7 @@ __all__ = [ 'AdministrativeActTreatmentFileModifForm', 'DashboardTreatmentForm', 'DashboardTreatmentFileForm', 'RecordFormSelection', 'FindForm', 'DateForm', 'DatingFormSet', - 'PreservationForm', + 'PreservationForm', 'FindBasketFormSelection', 'FindSelect', 'FindFormSelection', 'FindFormSelectionWarehouseModule', 'MultipleFindFormSelection', 'MultipleFindFormSelectionWarehouseModule', 'FindMultipleFormSelection', 'check_form', 'check_exist', 'check_not_exist', @@ -918,6 +919,34 @@ class UpstreamFindFormSelection(FindFormSelection): self.fields['resulting_pk'] = self.fields.pop('pk') +class FindBasketSelect(CustomForm, TableSelect): + _model = models.FindBasket + + form_admin_name = _(u"Find basket - 001 - Search") + form_slug = "findbasket-001-search" + search_vector = forms.CharField( + label=_(u"Full text search"), widget=widgets.SearchWidget( + 'archaeological-finds', 'findbasket' + )) + + label = forms.CharField(label=_(u"Denomination")) + + +class FindBasketFormSelection(CustomFormSearch): + SEARCH_AND_SELECT = True + form_label = _("Basket search") + associated_models = {'pk': models.FindBasket} + currents = {'pk': models.FindBasket} + + pk = forms.IntegerField( + label="", required=False, + widget=widgets.DataTable( + reverse_lazy('get-findbasket'), + FindBasketSelect, models.FindBasket, + ), + validators=[valid_id(models.FindBasket)]) + + class NewFindBasketForm(forms.ModelForm): class Meta: model = models.FindBasket @@ -959,7 +988,9 @@ class SelectFindBasketForm(IshtarForm): return self.fields['basket'].choices = [('', '--')] + [ (b.pk, unicode(b)) - for b in models.FindBasket.objects.filter(user=self.user)] + for b in models.FindBasket.objects.filter( + Q(user=self.user) | Q(shared_with=self.user) + )] class DeleteFindBasketForm(SelectFindBasketForm): @@ -979,8 +1010,9 @@ class FindBasketAddItemForm(forms.Form): def save(self, user): try: - basket = models.FindBasket.objects.get( - pk=self.cleaned_data['basket_id'], user=user) + basket = models.FindBasket.objects.filter( + Q(user=user) | Q(shared_with=user) + ).get(pk=self.cleaned_data['basket_id']) item = models.Find.objects.get( pk=self.cleaned_data['item_id']) except models.FindBasket.DoesNotExist or\ diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py index c72e9c089..3dd98bdbd 100644 --- a/archaeological_finds/ishtar_menu.py +++ b/archaeological_finds/ishtar_menu.py @@ -24,7 +24,7 @@ from ishtar_common.menu_base import SectionItem, MenuItem from archaeological_operations.models import AdministrativeAct import models -# be carreful: each access_controls must be relevant with check_rights in urls +# be careful: each access_controls must be relevant with check_rights in urls MENU_SECTIONS = [ (50, @@ -56,22 +56,27 @@ MENU_SECTIONS = [ SectionItem( 'find_basket', _(u"Basket"), childs=[ + MenuItem('find_basket_search', + _(u"Search"), + model=models.FindBasket, + access_controls=['view_find', + 'view_own_find']), MenuItem('find_basket_creation', _(u"Creation"), model=models.FindBasket, - access_controls=['change_find', - 'change_own_find']), + access_controls=['view_find', + 'view_own_find']), MenuItem('find_basket_modification_add', _(u"Manage items"), model=models.FindBasket, access_controls=[ - 'change_find', - 'change_own_find']), + 'view_find', + 'view_own_find']), MenuItem('find_basket_deletion', _(u"Deletion"), model=models.FindBasket, - access_controls=['change_find', - 'change_own_find']), + access_controls=['view_find', + 'view_own_find']), ]), # MenuItem( # 'treatment_creation', _(u"Add a treatment"), diff --git a/archaeological_finds/migrations/0037_auto_20181018_1756.py b/archaeological_finds/migrations/0037_auto_20181018_1756.py new file mode 100644 index 000000000..0a91b860c --- /dev/null +++ b/archaeological_finds/migrations/0037_auto_20181018_1756.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-10-18 17:56 +from __future__ import unicode_literals + +import django.contrib.postgres.search +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0074_auto_20181017_1854'), + ('archaeological_finds', '0036_auto_20181017_1854'), + ] + + operations = [ + migrations.AlterModelOptions( + name='findbasket', + options={'permissions': (('view_find', 'Can view all Finds'), ('view_own_find', 'Can view own Find'))}, + ), + migrations.AddField( + model_name='findbasket', + name='search_vector', + field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto filled at save', null=True, verbose_name='Search vector'), + ), + migrations.AddField( + model_name='findbasket', + name='shared_with', + field=models.ManyToManyField(blank=True, related_name='shared_findbaskets', to='ishtar_common.IshtarUser', verbose_name='Shared with'), + ), + migrations.AlterField( + model_name='findbasket', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='findbaskets', to='ishtar_common.IshtarUser', verbose_name='Owner'), + ), + migrations.AlterUniqueTogether( + name='findbasket', + unique_together=set([]), + ), + ] diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index e0ba9206a..f6c8c6bf6 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -566,9 +566,19 @@ WEIGHT_UNIT = (('g', _(u"g")), ('kg', _(u"kg")),) -class FindBasket(Basket): +class FindBasket(Basket, OwnPerms): items = models.ManyToManyField('Find', blank=True, related_name='basket') + class Meta: + permissions = ( + ("view_find", u"Can view all Finds"), + ("view_own_find", u"Can view own Find"), + ) + + @classmethod + def get_query_owns(cls, ishtaruser): + return Q(user=ishtaruser) + class FirstBaseFindView(object): CREATE_SQL = """ @@ -708,7 +718,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, 'base_finds__find__description': 'base_finds__find__description__icontains', 'base_finds__batch': 'base_finds__batch', - 'basket': 'basket', + 'basket_id': 'basket__pk', 'denomination': 'denomination', 'cached_label': 'cached_label__icontains', 'documents__image__isnull': 'documents__image__isnull', diff --git a/archaeological_finds/templates/ishtar/sheet_findbasket.html b/archaeological_finds/templates/ishtar/sheet_findbasket.html index b6d4ffd42..c9c442ccd 100644 --- a/archaeological_finds/templates/ishtar/sheet_findbasket.html +++ b/archaeological_finds/templates/ishtar/sheet_findbasket.html @@ -1,13 +1,24 @@ {% extends "ishtar/sheet.html" %} {% load i18n window_tables window_header from_dict window_field %} -{% block head_title %}{% trans "Find basket" %}{% endblock %} +{% block head_title %}{% trans "Basket" %} - {{item.label}}{% endblock %} + +{% block toolbar %} +{% window_nav item window_id 'show-findbasket' 'select_itemsinbasket' %} +{% endblock %} {% block content %} -{% window_nav item window_id 'show-findbasket' 'select_itemsinbasket' %} -<p class="window-refs">{{ item.label|default:"" }}</p> -{% field "Owned by" item.user %} -{% field "Comment" item.comment %} -{% dynamic_table_document finds 'finds_for_ope' 'basket' item.pk 'TABLE_COLS_FOR_OPE' output %} +<div class='row'> + {% field_flex "Label" item.label %} + {% field_flex_detail "Owned by" item.user.person %} + {% field_flex_multiple "Shared_with" item.shared_with %} + {% field_flex "Comment" item.comment %} +</div> + +<h3>{% trans "Content" %}</h3> + +{% dynamic_table_document finds 'finds' 'basket_id' item.pk 'TABLE_COLS' output %} + + {% endblock %} diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index 9629a3f38..afc9bcba7 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -43,32 +43,37 @@ urlpatterns = [ views.find_deletion_wizard), name='find_deletion'), url(r'find_modify/(?P<pk>.+)/$', views.find_modify, name='find_modify'), + url(r'get-findbasket/$', views.get_find_basket, + name='get-findbasket'), + url(r'find_basket_search/(?P<step>.+)?$', + check_rights(['view_find', 'view_own_find'])( + views.basket_search_wizard), name='find_basket_search'), url(r'^find_basket_creation/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.NewFindBasketView.as_view()), name='new_findbasket'), url(r'^find_basket_modification_add/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.SelectBasketForManagement.as_view()), name='select_findbasketforadd'), url(r'^find_basket_modification_add/(?P<pk>[0-9]+)?/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.SelectItemsInBasket.as_view()), name='select_itemsinbasket'), url(r'^find_basket_modification_add_item/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.FindBasketAddItemView.as_view()), name='add_iteminbasket'), url(r'^find_basket_modification_delete_item/(?P<basket>[0-9]+)?' r'/(?P<find_pk>[0-9]+)?/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.FindBasketDeleteItemView.as_view()), name='delete_iteminbasket'), url(r'^find_basket_list/(?P<pk>[0-9]+)?/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.FindBasketListView.as_view()), name='list_iteminbasket'), url(r'^find_basket_deletion/$', - check_rights(['change_find', 'change_own_find'])( + check_rights(['view_find', 'view_own_find'])( views.DeleteFindBasketView.as_view()), name='delete_findbasket'), url(r'^find-qa-bulk-update/(?P<pks>[0-9-]+)?/$', diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 7855b5099..7523df145 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -113,6 +113,16 @@ show_findbasket = show_item(models.FindBasket, 'findbasket') display_findbasket = display_item(models.FindBasket, show_url='show-find/basket-') +get_find_basket = get_item( + models.FindBasket, 'get_findbasket', 'findbasket', +) + +basket_search_wizard = FindBasketSearch.as_view( + [('general-basket_search', FindBasketFormSelection)], + label=_(u"Basket search"), + url_name='find_basket_search', +) + def check_preservation_module(self): return get_current_profile().preservation @@ -234,6 +244,16 @@ class NewFindBasketView(IshtarMixin, LoginRequiredMixin, CreateView): return HttpResponseRedirect(self.get_success_url()) +class OwnBasket(object): + def get_basket(self, user, pk): + try: + return models.FindBasket.objects.filter( + Q(user=user) | Q(shared_with=user) + ).get(pk=pk) + except models.FindBasket.DoesNotExist: + raise PermissionDenied + + class SelectBasketForManagement(IshtarMixin, LoginRequiredMixin, FormView): template_name = 'ishtar/form.html' form_class = SelectFindBasketForm @@ -255,7 +275,8 @@ class SelectBasketForManagement(IshtarMixin, LoginRequiredMixin, FormView): form.cleaned_data['basket'])) -class SelectItemsInBasket(IshtarMixin, LoginRequiredMixin, TemplateView): +class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin, + TemplateView): template_name = 'ishtar/manage_basket.html' page_name = _(u"Manage basket") @@ -263,11 +284,9 @@ class SelectItemsInBasket(IshtarMixin, LoginRequiredMixin, TemplateView): context = super(SelectItemsInBasket, self).get_context_data( *args, **kwargs) self.user = IshtarUser.objects.get(pk=self.request.user.pk) - try: - self.basket = models.FindBasket.objects.get( - pk=self.kwargs['pk'], user=self.user) - except models.FindBasket.DoesNotExist: - raise PermissionDenied + self.basket = self.get_basket( + user=self.user, pk=self.kwargs['pk'] + ) context['basket'] = self.basket if get_current_profile().warehouse: context['form'] = MultipleFindFormSelectionWarehouseModule() @@ -296,18 +315,17 @@ class FindBasketAddItemView(IshtarMixin, LoginRequiredMixin, FormView): return HttpResponseRedirect(self.get_success_url(basket)) -class FindBasketListView(IshtarMixin, LoginRequiredMixin, TemplateView): +class FindBasketListView(OwnBasket, IshtarMixin, LoginRequiredMixin, + TemplateView): template_name = 'ishtar/basket_list.html' def get_context_data(self, *args, **kwargs): context = super(FindBasketListView, self).get_context_data( *args, **kwargs) self.user = IshtarUser.objects.get(pk=self.request.user.pk) - try: - self.basket = models.FindBasket.objects.get( - pk=self.kwargs['pk'], user=self.user) - except models.FindBasket.DoesNotExist: - raise PermissionDenied + self.basket = self.get_basket( + user=self.user, pk=self.kwargs['pk'] + ) context['basket'] = self.basket context['item_url'] = '/'.join( reverse(models.Find.SHOW_URL, args=[1]).split('/')[:-1]) @@ -316,7 +334,8 @@ class FindBasketListView(IshtarMixin, LoginRequiredMixin, TemplateView): return context -class FindBasketDeleteItemView(IshtarMixin, LoginRequiredMixin, TemplateView): +class FindBasketDeleteItemView(OwnBasket, IshtarMixin, LoginRequiredMixin, + TemplateView): template_name = 'ishtar/simple_form.html' def get_success_url(self, basket): @@ -330,11 +349,10 @@ class FindBasketDeleteItemView(IshtarMixin, LoginRequiredMixin, TemplateView): pk=self.kwargs['find_pk']) except models.Find.DoesNotExist: raise PermissionDenied - try: - basket = models.FindBasket.objects.get( - pk=self.kwargs['basket'], user=ishtaruser) - except models.FindBasket.DoesNotExist: - raise PermissionDenied + + basket = self.get_basket( + user=ishtaruser, pk=self.kwargs['basket'] + ) if not user.is_superuser and \ not ishtaruser.has_right('view_find') and \ not (ishtaruser.has_right('view_own_find') diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index 6486e5da1..ef51d85d1 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -230,3 +230,7 @@ class TreatmentFileEditAdministrativeActWizard( def get_associated_item(self, dct): return self.get_current_object().treatment_file + + +class FindBasketSearch(SearchWizard): + model = models.FindBasket |