From 9a71511b55615c2b83d8dee18e1863391ab95654 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 16 Nov 2018 17:55:00 +0100 Subject: Wizard: display selected on final wizard panel --- ishtar_common/wizards.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ishtar_common/wizards.py') diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index a439cc014..7fd19f721 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -1181,7 +1181,7 @@ class Wizard(IshtarWizard): return vals def get_current_object(self): - """Get the current object for an instancied wizard""" + """Get the current object for an instanced wizard""" current_obj = None for key in self.main_item_select_keys: main_form_key = key + self.url_name -- cgit v1.2.3 From e1dd8ec6a19febe27642dd2411aaaa1cf5c8bdaa Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 21 Nov 2018 10:22:04 +0100 Subject: Manage treatment with no creation new of item --- archaeological_files/wizards.py | 4 +- archaeological_finds/admin.py | 5 ++- archaeological_finds/forms.py | 7 +-- .../migrations/0040_auto_20181120_1027.py | 33 ++++++++++++++ archaeological_finds/models_finds.py | 4 ++ archaeological_finds/models_treatments.py | 51 +++++++++++++++------- archaeological_finds/wizards.py | 38 +++++++++++----- archaeological_operations/wizards.py | 2 +- archaeological_warehouse/wizards.py | 2 +- ishtar_common/wizards.py | 8 ++-- 10 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 archaeological_finds/migrations/0040_auto_20181120_1027.py (limited to 'ishtar_common/wizards.py') diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py index 106008192..c9b1ba9c2 100644 --- a/archaeological_files/wizards.py +++ b/archaeological_files/wizards.py @@ -43,8 +43,8 @@ class FileWizard(OperationWizard): town_step_keys = ['towns-'] wizard_done_window = reverse_lazy('show-file') - def get_extra_model(self, dct, form_list): - dct = super(FileWizard, self).get_extra_model(dct, form_list) + def get_extra_model(self, dct, m2m, form_list): + dct = super(FileWizard, self).get_extra_model(dct, m2m, form_list) if not dct.get('numeric_reference'): current_ref = models.File.objects.filter(year=dct['year'])\ .aggregate(Max('numeric_reference'))["numeric_reference__max"] diff --git a/archaeological_finds/admin.py b/archaeological_finds/admin.py index 1513c7eeb..033d5bb96 100644 --- a/archaeological_finds/admin.py +++ b/archaeological_finds/admin.py @@ -157,7 +157,10 @@ admin_site.register(models.CommunicabilityType, HierarchicalTypeAdmin) class TreatmentTypeAdmin(GeneralTypeAdmin): list_display = HierarchicalTypeAdmin.list_display + [ - 'order', 'virtual', 'upstream_is_many', 'downstream_is_many'] + 'order', 'virtual', 'destructive', 'create_new_find', + 'upstream_is_many', 'downstream_is_many'] + list_filter = ['virtual', 'destructive', 'create_new_find', + 'upstream_is_many', 'downstream_is_many'] model = models.TreatmentType diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index b95ac90c6..90e1390bf 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -532,19 +532,20 @@ class QAFindFormMulti(QAForm): MULTI = True REPLACE_FIELDS = [ - 'qa_ue', 'qa_manufacturing_place', 'qa_checked_type', 'qa_check_date' + 'qa_denomination', 'qa_ue', 'qa_manufacturing_place', 'qa_checked_type', + 'qa_check_date' ] HEADERS = { 'qa_ue': FormHeader(_(u"Context record")), - 'qa_label': FormHeader(_(u"Identification")), + 'qa_denomination': FormHeader(_(u"Identification")), 'qa_description': FormHeader(_(u"Description")), 'qa_checked_type': FormHeader(_(u"Sheet")), 'qa_period': FormHeader(_(u"Datation")), } SINGLE_FIELDS = [ - 'qa_label', 'qa_denomination', 'qa_previous_id', + 'qa_label', 'qa_previous_id', 'qa_get_first_base_find__excavation_id', 'qa_museum_id', 'qa_seal_number', 'qa_mark' ] diff --git a/archaeological_finds/migrations/0040_auto_20181120_1027.py b/archaeological_finds/migrations/0040_auto_20181120_1027.py new file mode 100644 index 000000000..fd649dd8f --- /dev/null +++ b/archaeological_finds/migrations/0040_auto_20181120_1027.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-11-20 10:27 +from __future__ import unicode_literals + +from django.db import migrations, models + + +def init_create_new_find(apps, schema): + TreatmentType = apps.get_model('archaeological_finds', 'TreatmentType') + for tp in TreatmentType.objects.all(): + if (tp.upstream_is_many or tp.downstream_is_many) and not tp.virtual: + tp.create_new_find = True + tp.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('archaeological_finds', '0039_auto_20181115_1649'), + ] + + operations = [ + migrations.AlterModelOptions( + name='treatment', + options={'ordering': ('start_date',), 'permissions': (('view_treatment', 'Can view all Treatments'), ('view_own_treatment', 'Can view own Treatment'), ('add_own_treatment', 'Can add own Treatment'), ('change_own_treatment', 'Can change own Treatment'), ('delete_own_treatment', 'Can delete own Treatment')), 'verbose_name': 'Treatment', 'verbose_name_plural': 'Treatments'}, + ), + migrations.AddField( + model_name='treatmenttype', + name='create_new_find', + field=models.BooleanField(default=False, help_text='If True when this treatment is applied a new version of the object will be created.', verbose_name='Create a new find'), + ), + migrations.RunPython(init_create_new_find) + ] diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index e856cb8ca..c7bd3f64e 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -92,6 +92,10 @@ class TreatmentType(HierarchicalType): order = models.IntegerField(_(u"Order"), default=10) virtual = models.BooleanField(_(u"Virtual")) destructive = models.BooleanField(_(u"Destructive"), default=False) + create_new_find = models.BooleanField( + _(u"Create a new find"), default=False, + help_text=_(u"If True when this treatment is applied a new version " + u"of the object will be created.")) upstream_is_many = models.BooleanField( _(u"Upstream is many"), default=False, help_text=_( diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index 68935f142..b1ad5fa41 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -74,7 +74,8 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, } # extra keys than can be passed to save method EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items', - 'resulting_finds', 'upstream_item') + 'resulting_finds', 'upstream_item', + 'treatment_type_list') # alternative names of fields for searches ALT_NAMES = { @@ -295,7 +296,8 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, if q.count(): self.index = q.all().aggregate(Max('index'))['index__max'] + 1 - def _create_n_1_resulting_find(self, resulting_find, upstream_items): + def _create_n_1_resulting_find(self, resulting_find, upstream_items, + treatment_types): """ Manage creation of n<->1 treatment """ @@ -319,6 +321,9 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, except TypeError: m2m_field.add(m2m[k]) + create_new_find = bool([tp for tp in treatment_types + if tp.create_new_find]) + dating_keys = ["period", "start_date", "end_date", "dating_type", "quality", "precise_dating"] current_datings = [] @@ -361,14 +366,19 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, new_find.data = update_data(new_find.data, upstream_item.data, merge=True) - upstream_item.downstream_treatment = self - upstream_item.history_modifier = self.history_modifier - upstream_item.save() + if create_new_find: + upstream_item.downstream_treatment = self + upstream_item.history_modifier = self.history_modifier + upstream_item.save() + else: + self.finds.add(upstream_item) + new_find.upstream_treatment = self new_find.skip_history_when_saving = True new_find.save() - def _create_1_n_resulting_find(self, resulting_finds, upstream_item, user): + def _create_1_n_resulting_find(self, resulting_finds, upstream_item, user, + treatment_types): """ Manage creation of 1<->n treatment """ @@ -384,9 +394,15 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, new_find.save() new_items.append(new_find) - upstream_item.downstream_treatment = self - upstream_item.skip_history_when_saving = True - upstream_item.save() + create_new_find = bool([tp for tp in treatment_types + if tp.create_new_find]) + + if create_new_find: + upstream_item.downstream_treatment = self + upstream_item.skip_history_when_saving = True + upstream_item.save() + else: + self.finds.add(upstream_item) if getattr(user, 'ishtaruser', None): b = FindBasket.objects.create( @@ -397,6 +413,7 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, def save(self, *args, **kwargs): items, user, extra_args_for_new, resulting_find = [], None, [], None upstream_items, upstream_item, resulting_finds = [], None, None + treatment_types = [] if "items" in kwargs: items = kwargs.pop('items') if "resulting_find" in kwargs: @@ -411,6 +428,8 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, user = kwargs.pop('user') if "extra_args_for_new" in kwargs: extra_args_for_new = kwargs.pop('extra_args_for_new') + if "treatment_type_list" in kwargs: + treatment_types = kwargs.pop('treatment_type_list') self.pre_save() super(Treatment, self).save(*args, **kwargs) updated = [] @@ -421,18 +440,20 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, upstream_items = upstream_items.items.all() if upstream_items and resulting_find: - self._create_n_1_resulting_find(resulting_find, upstream_items) + self._create_n_1_resulting_find(resulting_find, upstream_items, + treatment_types) return if upstream_item and resulting_finds: - self._create_1_n_resulting_find(resulting_finds, upstream_item, - self.history_modifier) + self._create_1_n_resulting_find( + resulting_finds, upstream_item, self.history_modifier, + treatment_types) return - tps = list(self.treatment_types.all()) - has_destructive_tp = bool([tp for tp in tps if tp.destructive]) + create_new_find = bool([tp for tp in treatment_types + if tp.create_new_find]) for item in items: - if not has_destructive_tp: + if not create_new_find: self.finds.add(item) else: new = item.duplicate(user) diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index bd16a55de..29ca50056 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -86,8 +86,8 @@ class FindWizard(Wizard): (_(u"Context record"), unicode(current_cr))) return context - def get_extra_model(self, dct, form_list): - dct = super(FindWizard, self).get_extra_model(dct, form_list) + def get_extra_model(self, dct, m2m, form_list): + dct = super(FindWizard, self).get_extra_model(dct, m2m, form_list) dct['order'] = 1 if 'pk' in dct and type(dct['pk']) == ContextRecord: dct['base_finds__context_record'] = dct.pop('pk') @@ -125,6 +125,7 @@ class TreatmentBase(Wizard): model = models.Treatment wizard_done_window = reverse_lazy('show-treatment') base_url = "" + saved_args = {"treatment_type_list": []} def get_current_finds(self): step = self.steps.current @@ -158,10 +159,20 @@ class TreatmentBase(Wizard): initial['location'] = locations[0] return initial + def get_extra_model(self, dct, m2m, form_list): + dct = super(TreatmentBase, self).get_extra_model(dct, m2m, form_list) + dct['treatment_type_list'] = [] + for k, v in m2m: + if k == 'treatment_type': + if type(v) not in (list, tuple): + v = [v] + dct['treatment_type_list'] += v + return dct + class TreatmentWizard(TreatmentBase): basket_step = 'basetreatment-treatment_creation' - saved_args = {"items": []} + saved_args = {"items": [], "treatment_type_list": []} base_url = 'treatment_creation' def get_form_kwargs(self, step, **kwargs): @@ -171,11 +182,11 @@ class TreatmentWizard(TreatmentBase): kwargs['user'] = self.request.user return kwargs - def get_extra_model(self, dct, form_list): + def get_extra_model(self, dct, m2m, form_list): """ Get items concerned by the treatment """ - dct = super(TreatmentWizard, self).get_extra_model(dct, form_list) + dct = super(TreatmentWizard, self).get_extra_model(dct, m2m, form_list) if 'resulting_pk' in dct: dct['items'] = [] pks = dct.pop('resulting_pk').split(u',') @@ -203,7 +214,8 @@ class TreatmentModificationWizard(TreatmentWizard): class TreatmentN1Wizard(TreatmentBase): - saved_args = {"upstream_items": [], "resulting_find": None} + saved_args = {"upstream_items": [], "resulting_find": None, + "treatment_type_list": []} base_url = 'treatment_creation_n1' def _update_simple_initial_from_finds(self, initial, find, k): @@ -282,11 +294,12 @@ class TreatmentN1Wizard(TreatmentBase): initial.pop(k) return initial - def get_extra_model(self, dct, form_list): + def get_extra_model(self, dct, m2m, form_list): """ Get items concerned by the treatment """ - dct = super(TreatmentN1Wizard, self).get_extra_model(dct, form_list) + dct = super(TreatmentN1Wizard, self).get_extra_model( + dct, m2m, form_list) if 'resulting_pk' not in dct: return dct @@ -318,7 +331,8 @@ class TreatmentN1Wizard(TreatmentBase): class Treatment1NWizard(TreatmentBase): - saved_args = {"upstream_item": None, "resulting_finds": None} + saved_args = {"upstream_item": None, "resulting_finds": None, + "treatment_type_list": []} base_url = 'treatment_creation_1n' def get_form_kwargs(self, step, **kwargs): @@ -340,11 +354,12 @@ class Treatment1NWizard(TreatmentBase): initial['resultings_label'] = lbl + u"-" return initial - def get_extra_model(self, dct, form_list): + def get_extra_model(self, dct, m2m, form_list): """ Get items concerned by the treatment """ - dct = super(Treatment1NWizard, self).get_extra_model(dct, form_list) + dct = super(Treatment1NWizard, self).get_extra_model( + dct, m2m, form_list) if 'resulting_pk' not in dct: return dct @@ -373,7 +388,6 @@ class Treatment1NWizard(TreatmentBase): u"resulting items. This search have been pinned.") ).format(dct["resulting_finds"]["basket_name"]) ) - self.request.session["pin-search-find"] = u'{}="{}"'.format( unicode(pgettext("key for text search", u"basket")), dct["resulting_finds"]["basket_name"]) diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index de38beb95..798e622b4 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -332,7 +332,7 @@ class OperationAdministrativeActWizard(OperationWizard): except models.AdministrativeAct.DoesNotExist: return - def get_extra_model(self, dct, form_list): + def get_extra_model(self, dct, m2m, form_list): dct['history_modifier'] = self.request.user return dct diff --git a/archaeological_warehouse/wizards.py b/archaeological_warehouse/wizards.py index 8ee2c2972..a0d46e892 100644 --- a/archaeological_warehouse/wizards.py +++ b/archaeological_warehouse/wizards.py @@ -49,7 +49,7 @@ class PackagingWizard(TreatmentWizard): def save_model(self, dct, m2m, whole_associated_models, form_list, return_object): - dct = self.get_extra_model(dct, form_list) + dct = self.get_extra_model(dct, m2m, form_list) obj = self.get_current_saved_object() dct['location'] = dct['container'].location items = None diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 7fd19f721..b3fc4b55a 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -439,7 +439,7 @@ class Wizard(IshtarWizard): datas.append((form.form_label, form_datas)) return datas - def get_extra_model(self, dct, form_list): + def get_extra_model(self, dct, m2m, form_list): dct['history_modifier'] = self.request.user return dct @@ -552,7 +552,7 @@ class Wizard(IshtarWizard): def save_model(self, dct, m2m, whole_associated_models, form_list, return_object): - dct = self.get_extra_model(dct, form_list) + dct = self.get_extra_model(dct, m2m, form_list) obj = self.get_current_saved_object() data = {} if obj and hasattr(obj, 'data'): @@ -1787,8 +1787,8 @@ class AccountWizard(Wizard): class SourceWizard(Wizard): model = None - def get_extra_model(self, dct, form_list): - dct = super(SourceWizard, self).get_extra_model(dct, form_list) + def get_extra_model(self, dct, m2m, form_list): + dct = super(SourceWizard, self).get_extra_model(dct, m2m, form_list) if 'history_modifier' in dct: dct.pop('history_modifier') return dct -- cgit v1.2.3 From afd7fb9c2be01a44a45f582eebdf02632a10be99 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 29 Nov 2018 19:34:31 +0100 Subject: Basket: manage basket share (ro and edit) - manage alt query own --- archaeological_finds/forms.py | 72 +++++++++++++++++++--- .../migrations/0042_auto_20181129_1755.py | 30 +++++++++ archaeological_finds/models_finds.py | 24 +++++--- .../templates/ishtar/sheet_findbasket.html | 3 +- archaeological_finds/urls.py | 2 + archaeological_finds/views.py | 17 +++-- archaeological_finds/wizards.py | 1 + .../migrations/0077_auto_20181129_1755.py | 20 ++++++ ishtar_common/models.py | 17 +++-- .../blocks/window_field_flex_multiple_full.html | 8 +++ ishtar_common/templates/ishtar/form.html | 3 + ishtar_common/templatetags/window_field.py | 8 +++ ishtar_common/urls.py | 2 + ishtar_common/views.py | 23 +++++++ ishtar_common/views_item.py | 60 +++++++++++------- ishtar_common/wizards.py | 18 ++++-- scss/custom.scss | 1 + 17 files changed, 256 insertions(+), 53 deletions(-) create mode 100644 archaeological_finds/migrations/0042_auto_20181129_1755.py create mode 100644 ishtar_common/migrations/0077_auto_20181129_1755.py create mode 100644 ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html (limited to 'ishtar_common/wizards.py') diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 90e1390bf..811e71a60 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -57,7 +57,7 @@ from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \ PkWizardSearch from ishtar_common.forms_common import get_town_field from ishtar_common.models import valid_id, valid_ids, get_current_profile, \ - SpatialReferenceSystem, Area, OperationType + SpatialReferenceSystem, Area, OperationType, IshtarUser from ishtar_common.utils import convert_coordinates_to_point __all__ = [ @@ -74,6 +74,7 @@ __all__ = [ 'DashboardTreatmentForm', 'DashboardTreatmentFileForm', 'RecordFormSelection', 'FindForm', 'SimpleFindForm', 'DateForm', 'DatingFormSet', 'PreservationForm', 'FindBasketFormSelection', + 'FindBasketForWriteFormSelection', 'FindBasketForm', 'FindSelect', 'FindFormSelection', 'FindFormSelectionWarehouseModule', 'MultipleFindFormSelection', 'MultipleFindFormSelectionWarehouseModule', 'FindMultipleFormSelection', @@ -883,7 +884,8 @@ class FindSelect(HistorySelect): if self.current_user: self.fields['basket'].choices += [ (b.pk, b.label) for b in models.FindBasket.objects.filter( - user=self.current_user).all()] + models.FindBasket.get_query_owns(self.current_user) + ).all()] def get_input_ids(self): ids = super(FindSelect, self).get_input_ids() @@ -1169,19 +1171,57 @@ class FindBasketFormSelection(CustomFormSearch): validators=[valid_id(models.FindBasket)]) +class FindBasketForWriteFormSelection(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-write'), + FindBasketSelect, models.FindBasket, + ), + validators=[valid_id(models.FindBasket)]) + + class FindBasketForm(IshtarForm): form_label = _(u"Find basket") + associated_models = {"shared_with": IshtarUser, + "shared_write_with": IshtarUser} label = forms.CharField( label=_(u"Label"), validators=[validators.MaxLengthValidator(1000)]) comment = forms.CharField(label=_(u"Comment"), widget=forms.Textarea, required=False) + shared_with = widgets.Select2MultipleField( + model=IshtarUser, remote=True, + label=_(u"Shared (read) with"), + required=False, long_widget=True + ) + shared_write_with = widgets.Select2MultipleField( + model=IshtarUser, remote=True, + label=_(u"Shared (read/edit) with"), + required=False, long_widget=True + ) -class NewFindBasketForm(forms.ModelForm): +class NewFindBasketForm(forms.ModelForm, IshtarForm): + shared_with = widgets.Select2MultipleField( + model=IshtarUser, remote=True, + label=_(u"Shared (read) with"), + required=False, long_widget=True + ) + shared_write_with = widgets.Select2MultipleField( + model=IshtarUser, remote=True, + label=_(u"Shared (read/edit) with"), + required=False, long_widget=True + ) + class Meta: model = models.FindBasket - fields = ('label', 'comment') + fields = ('label', 'comment', 'shared_with', 'shared_write_with') def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') @@ -1217,14 +1257,26 @@ class SelectFindBasketForm(IshtarForm): super(SelectFindBasketForm, self).__init__(*args, **kwargs) if not self.user: return - self.fields['basket'].choices = [('', '--')] + [ - (b.pk, unicode(b)) + self.fields['basket'].choices = self.get_basket_choices() + + def get_basket_choices(self): + return [('', u'--')] + [ + (str(b.pk), unicode(b)) for b in models.FindBasket.objects.filter( - Q(user=self.user) | Q(shared_with=self.user) - )] + Q(user=self.user) | Q(shared_write_with=self.user) + ) + ] class DeleteFindBasketForm(SelectFindBasketForm): + def get_basket_choices(self): + return [('', u'--')] + [ + (str(b.pk), unicode(b)) + for b in models.FindBasket.objects.filter( + Q(user=self.user) + ) + ] + def save(self): try: models.FindBasket.objects.get(pk=self.cleaned_data['basket'], @@ -1242,8 +1294,8 @@ class FindBasketAddItemForm(forms.Form): def save(self, user): try: basket = models.FindBasket.objects.filter( - Q(user=user) | Q(shared_with=user) - ).get(pk=self.cleaned_data['basket_id']) + Q(user=user) | Q(shared_with=user) | Q(shared_write_with=user) + ).distinct().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/migrations/0042_auto_20181129_1755.py b/archaeological_finds/migrations/0042_auto_20181129_1755.py new file mode 100644 index 000000000..42d732cf2 --- /dev/null +++ b/archaeological_finds/migrations/0042_auto_20181129_1755.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-11-29 17:55 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0077_auto_20181129_1755'), + ('archaeological_finds', '0041_auto_20181121_1225'), + ] + + operations = [ + migrations.AlterModelOptions( + name='treatmentfile', + options={'ordering': ('cached_label',), 'permissions': (('view_treatmentfile', 'Can view all Treatment requests'), ('view_own_treatmentfile', 'Can view own Treatment request'), ('add_own_treatmentfile', 'Can add own Treatment request'), ('change_own_treatmentfile', 'Can change own Treatment request'), ('delete_own_treatmentfile', 'Can delete own Treatment request')), 'verbose_name': 'Treatment request', 'verbose_name_plural': 'Treatment requests'}, + ), + migrations.AddField( + model_name='findbasket', + name='shared_write_with', + field=models.ManyToManyField(blank=True, related_name='shared_write_findbaskets', to='ishtar_common.IshtarUser', verbose_name='Shared (read/edit) with'), + ), + migrations.AlterField( + model_name='findbasket', + name='shared_with', + field=models.ManyToManyField(blank=True, related_name='shared_findbaskets', to='ishtar_common.IshtarUser', verbose_name='Shared (read) with'), + ), + ] diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 9baced4e0..0c9770186 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -591,6 +591,11 @@ class FindBasket(Basket, OwnPerms): @classmethod def get_query_owns(cls, ishtaruser): + return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q( + shared_write_with=ishtaruser) + + @classmethod + def get_write_query_owns(cls, ishtaruser): return Q(user=ishtaruser) def get_extra_actions(self, request): @@ -599,13 +604,18 @@ class FindBasket(Basket, OwnPerms): """ # url, base_text, icon, extra_text, extra css class, is a quick action - # no particular rights: if you can view an itm you can add it to your - # own basket - actions = [ - (reverse("select_itemsinbasket", args=[self.pk]), - _(u"Manage basket"), - "fa fa-shopping-basket", "", "", False), - ] + if not request.user or not request.user.ishtaruser: + return [] + + ishtaruser = request.user.ishtaruser + actions = [] + if self.user == ishtaruser or ishtaruser.pk in [ + user.pk for user in self.shared_write_with.all()]: + actions = [ + (reverse("select_itemsinbasket", args=[self.pk]), + _(u"Manage basket"), + "fa fa-shopping-basket", "", "", False), + ] return actions diff --git a/archaeological_finds/templates/ishtar/sheet_findbasket.html b/archaeological_finds/templates/ishtar/sheet_findbasket.html index 3c3ca1d3f..4a101d8f2 100644 --- a/archaeological_finds/templates/ishtar/sheet_findbasket.html +++ b/archaeological_finds/templates/ishtar/sheet_findbasket.html @@ -12,8 +12,9 @@
{% 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 %} + {% field_flex_multiple_full "Shared (read) with" item.shared_with %} + {% field_flex_multiple_full "Shared (read/edit) with" item.shared_write_with %}

{% trans "Content" %}

diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index 6e9f59b8c..0ef3bac89 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -45,6 +45,8 @@ urlpatterns = [ views.find_modify, name='find_modify'), url(r'get-findbasket/$', views.get_find_basket, name='get-findbasket'), + url(r'get-findbasket-write/$', views.get_find_basket_for_write, + name='get-findbasket-write'), url(r'find_basket_search/(?P.+)?$', check_rights(['view_find', 'view_own_find'])( views.basket_search_wizard), name='find_basket_search'), diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 29f0f75af..125567044 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -109,12 +109,19 @@ show_find = show_item(models.Find, 'find') display_find = display_item(models.Find) revert_find = revert_item(models.Find) -show_findbasket = show_item(models.FindBasket, 'findbasket') +show_findbasket = show_item(models.FindBasket, 'findbasket', + model_for_perms=models.Find) display_findbasket = display_item(models.FindBasket, show_url='show-find/basket-') get_find_basket = get_item( models.FindBasket, 'get_findbasket', 'findbasket', + model_for_perms=models.Find +) + +get_find_basket_for_write = get_item( + models.FindBasket, 'get_findbasket', 'findbasket', + model_for_perms=models.Find, alt_query_own='get_write_query_owns' ) basket_search_wizard = FindBasketSearch.as_view( @@ -125,10 +132,10 @@ basket_search_wizard = FindBasketSearch.as_view( basket_modify_wizard = FindBasketEditWizard.as_view( [ - ('selec-find_basket_modification', FindBasketFormSelection), + ('selec-find_basket_modification', FindBasketForWriteFormSelection), ('basket-find_basket_modification', FindBasketForm), ('final-find_basket_modification', FinalForm) - ], + ], label=_(u"Basket modify"), url_name='find_basket_modification', ) @@ -290,8 +297,8 @@ 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) + Q(user=user) | Q(shared_with=user) | Q(shared_write_with=user) + ).distinct().get(pk=pk) except models.FindBasket.DoesNotExist: raise PermissionDenied diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index 43f48ab59..6d4fd2d95 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -500,3 +500,4 @@ class FindBasketWizard(Wizard): class FindBasketEditWizard(FindBasketWizard): edit = True + alt_is_own_method = 'get_write_query_owns' diff --git a/ishtar_common/migrations/0077_auto_20181129_1755.py b/ishtar_common/migrations/0077_auto_20181129_1755.py new file mode 100644 index 000000000..bd9003946 --- /dev/null +++ b/ishtar_common/migrations/0077_auto_20181129_1755.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-11-29 17:55 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0076_migrate_treatmentfile_permissions'), + ] + + operations = [ + migrations.AlterField( + model_name='importertype', + name='is_template', + field=models.BooleanField(default=False, verbose_name='Can be exported'), + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 1aa94836f..1a0d80ac3 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -254,7 +254,7 @@ class OwnPerms(object): action_own_name, request.session) and self.is_own(request.user.ishtaruser)) - def is_own(self, user): + def is_own(self, user, alt_query_own=None): """ Check if the current object is owned by the user """ @@ -264,7 +264,10 @@ class OwnPerms(object): ishtaruser = user.ishtaruser else: return False - query = self.get_query_owns(ishtaruser) + if not alt_query_own: + query = self.get_query_owns(ishtaruser) + else: + query = getattr(self, alt_query_own)(ishtaruser) if not query: return False query &= Q(pk=self.pk) @@ -3293,6 +3296,7 @@ post_save.connect(post_save_userprofile, sender=UserProfile) class IshtarUser(FullSearch): + SLUG = "ishtaruser" TABLE_COLS = ('username', 'person__name', 'person__surname', 'person__email', 'person__person_types_list', 'person__attached_to__name') @@ -3441,9 +3445,13 @@ class Basket(FullSearch): verbose_name=_(u"Owner")) available = models.BooleanField(_(u"Available"), default=True) shared_with = models.ManyToManyField( - IshtarUser, verbose_name=_(u"Shared with"), blank=True, + IshtarUser, verbose_name=_(u"Shared (read) with"), blank=True, related_name='shared_%(class)ss' ) + shared_write_with = models.ManyToManyField( + IshtarUser, verbose_name=_(u"Shared (read/edit) with"), blank=True, + related_name='shared_write_%(class)ss' + ) TABLE_COLS = ['label', 'user'] @@ -3462,7 +3470,8 @@ class Basket(FullSearch): if not request.user or not getattr(request.user, 'ishtaruser', None): return Q(pk=None) ishtaruser = request.user.ishtaruser - return Q(user=ishtaruser) | Q(shared_with=ishtaruser) + return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q( + shared_write_with=ishtaruser) @property def cached_label(self): diff --git a/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html b/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html new file mode 100644 index 000000000..b70c1d2fc --- /dev/null +++ b/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html @@ -0,0 +1,8 @@ +{% load i18n %}{% if data.count %} +
+
{% trans caption %}
+
{% for d in data.distinct.all %} + {% if forloop.counter0 %} ; {% endif %}{{ d }} + {% endfor %}
+
+{% endif %} diff --git a/ishtar_common/templates/ishtar/form.html b/ishtar_common/templates/ishtar/form.html index b99d504a0..bcd69959e 100644 --- a/ishtar_common/templates/ishtar/form.html +++ b/ishtar_common/templates/ishtar/form.html @@ -1,5 +1,8 @@ {% extends "base.html" %} {% load i18n inline_formset table_form %} +{% block extra_head %} +{{form.media}} +{% endblock %} {% block pre_container %}
{% csrf_token %} diff --git a/ishtar_common/templatetags/window_field.py b/ishtar_common/templatetags/window_field.py index 46329a3fa..a5bae3b72 100644 --- a/ishtar_common/templatetags/window_field.py +++ b/ishtar_common/templatetags/window_field.py @@ -108,6 +108,14 @@ def field_flex_multiple(caption, data, small=False): return field_multiple(caption, data, size=size) +@register.inclusion_tag('ishtar/blocks/window_field_flex_multiple_full.html') +def field_flex_multiple_full(caption, data, small=False): + size = None + if small: + size = 2 + return field_multiple(caption, data, size=size) + + @register.inclusion_tag('ishtar/blocks/window_field_detail.html') def field_detail(caption, item, li=False, size=None): return {'caption': caption, 'item': item, 'link': link_to_window(item), diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index 8d06b6862..aea419d08 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -174,6 +174,8 @@ urlpatterns += [ views.new_person_noorga, name='new-person-noorga'), url(r'autocomplete-user/$', views.autocomplete_user, name='autocomplete-user'), + url(r'autocomplete-ishtaruser/$', + views.autocomplete_ishtaruser, name='autocomplete-ishtaruser'), url(r'autocomplete-person(?:/([0-9_]+))?(?:/([0-9_]*))?/(user)?$', views.autocomplete_person, name='autocomplete-person'), url(r'autocomplete-person-permissive(?:/([0-9_]+))?(?:/([0-9_]*))?' diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 3d64535d4..bc9c9432a 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -527,6 +527,29 @@ def autocomplete_user(request): return HttpResponse(data, content_type='text/plain') +def autocomplete_ishtaruser(request): + if not request.user.has_perm('ishtar_common.view_person', models.Person): + return HttpResponse('[]', content_type='text/plain') + q = request.GET.get('term') + limit = request.GET.get('limit', 20) + try: + limit = int(limit) + except ValueError: + return HttpResponseBadRequest() + query = Q() + for q in q.split(' '): + qu = (Q(person__name__icontains=q) | + Q(person__surname__icontains=q) | + Q(person__raw_name__icontains=q)) + query = query & qu + users = models.IshtarUser.objects.filter(query)[:limit] + data = json.dumps([ + {'id': user.pk, + 'value': unicode(user)} + for user in users]) + return HttpResponse(data, content_type='text/plain') + + def autocomplete_person(request, person_types=None, attached_to=None, is_ishtar_user=None, permissive=False): all_items = request.user.has_perm('ishtar_common.view_person', diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 71890fa6e..f34b2357f 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -133,22 +133,25 @@ def display_item(model, extra_dct=None, show_url=None): return func -def show_item(model, name, extra_dct=None): +def show_item(model, name, extra_dct=None, model_for_perms=None): def func(request, pk, **dct): - allowed, own = check_model_access_control(request, model) + check_model = model + if model_for_perms: + check_model = model_for_perms + allowed, own = check_model_access_control(request, check_model) if not allowed: return HttpResponse('', content_type="application/xhtml") q = model.objects if own: if not hasattr(request.user, 'ishtaruser'): - return HttpResponse('NOK') + return HttpResponse('') query_own = model.get_query_owns(request.user.ishtaruser) if query_own: q = q.filter(query_own).distinct() try: item = q.get(pk=pk) except ObjectDoesNotExist: - return HttpResponse('NOK') + return HttpResponse('') doc_type = 'type' in dct and dct.pop('type') url_name = u"/".join(reverse('show-' + name, args=['0', ''] ).split('/')[:-2]) + u"/" @@ -879,11 +882,13 @@ DEFAULT_ROW_NUMBER = 10 EXCLUDED_FIELDS = ['length'] -def get_item(model, func_name, default_name, extra_request_keys=[], - base_request=None, bool_fields=[], reversed_bool_fields=[], - dated_fields=[], associated_models=[], relative_session_names=[], - specific_perms=[], own_table_cols=None, relation_types_prefix={}, - do_not_deduplicate=False): +def get_item(model, func_name, default_name, extra_request_keys=None, + base_request=None, bool_fields=None, reversed_bool_fields=None, + dated_fields=None, associated_models=None, + relative_session_names=None, specific_perms=None, + own_table_cols=None, relation_types_prefix=None, + do_not_deduplicate=False, model_for_perms=None, + alt_query_own=None): """ Generic treatment of tables @@ -903,6 +908,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[], :param do_not_deduplicate: duplication of id can occurs on large queryset a mecanism of deduplication is used. But duplicate ids can be normal (for instance for record_relations view). + :param model_for_perms: use another model to check permission + :param alt_query_own: name of alternate method to get query_own :return: """ def func(request, data_type='json', full=False, force_own=False, @@ -914,10 +921,15 @@ def get_item(model, func_name, default_name, extra_request_keys=[], if 'type' in dct: data_type = dct.pop('type') if not data_type: - EMPTY = '[]' data_type = 'json' + if data_type == "json": + EMPTY = '[]' - allowed, own = check_model_access_control(request, model, + model_to_check = model + if model_for_perms: + model_to_check = model_for_perms + + allowed, own = check_model_access_control(request, model_to_check, available_perms) if not allowed: return HttpResponse(EMPTY, content_type='text/plain') @@ -933,13 +945,16 @@ def get_item(model, func_name, default_name, extra_request_keys=[], q = models.IshtarUser.objects.filter(user_ptr=request.user) if not q.count(): return HttpResponse(EMPTY, content_type='text/plain') - query_own = model.get_query_owns(q.all()[0]) + if alt_query_own: + query_own = getattr(model, alt_query_own)(q.all()[0]) + else: + query_own = model.get_query_owns(q.all()[0]) # 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) + my_extra_request_keys = copy(extra_request_keys or []) if base_request is None and hasattr(model, 'BASE_REQUEST'): if callable(model.BASE_REQUEST): my_base_request = model.BASE_REQUEST(request) @@ -952,32 +967,35 @@ def get_item(model, func_name, default_name, extra_request_keys=[], if not bool_fields and hasattr(model, 'BOOL_FIELDS'): my_bool_fields = model.BOOL_FIELDS[:] else: - my_bool_fields = bool_fields[:] + my_bool_fields = bool_fields[:] if bool_fields else [] 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[:] + my_reversed_bool_fields = reversed_bool_fields[:] \ + if reversed_bool_fields else [] if not dated_fields and hasattr(model, 'DATED_FIELDS'): my_dated_fields = model.DATED_FIELDS[:] else: - my_dated_fields = dated_fields[:] + my_dated_fields = dated_fields[:] if dated_fields else [] if not associated_models and hasattr(model, 'ASSOCIATED_MODELS'): my_associated_models = model.ASSOCIATED_MODELS[:] else: - my_associated_models = associated_models[:] + my_associated_models = associated_models[:] \ + if associated_models else [] 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[:] + my_relative_session_names = relative_session_names[:] \ + if relative_session_names else [] 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) + my_relation_types_prefix = copy(relation_types_prefix) \ + if relation_types_prefix else {} - fields = [model._meta.get_field(k) - for k in get_all_field_names(model)] + fields = [model._meta.get_field(k) for k in get_all_field_names(model)] request_keys = dict([ (field.name, diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index b3fc4b55a..19eb312e1 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -23,6 +23,7 @@ import os # from functools import wraps from django.conf import settings +from django.contrib import messages from formtools.wizard.views import NamedUrlWizardView, normalize_name, \ get_storage, StepsHelper @@ -115,6 +116,7 @@ class Wizard(IshtarWizard): ) main_item_select_keys = ('selec-',) formset_pop_deleted = True + alt_is_own_method = None # alternate method name for "is_own" check saved_args = {} # argument to pass on object save @@ -164,11 +166,17 @@ class Wizard(IshtarWizard): ishtaruser = request.user.ishtaruser \ if hasattr(request.user, 'ishtaruser') else None - # not the fisrt step and current object is not owned - if self.steps and self.steps.first != step and\ - current_object and not current_object.is_own(ishtaruser): - self.session_reset(request, self.url_name) - return HttpResponseRedirect('/') + # not the first step and current object is not owned + if self.steps and self.steps.first != step and current_object: + is_own = current_object.is_own( + ishtaruser, alt_query_own=self.alt_is_own_method) + if not is_own: + messages.add_message( + request, messages.WARNING, + _(u"Permission error: you cannot do this action.") + ) + self.session_reset(request, self.url_name) + return HttpResponseRedirect('/') # extra filter on forms self.filter_owns_items = True else: diff --git a/scss/custom.scss b/scss/custom.scss index 09074de0b..56dbffab6 100644 --- a/scss/custom.scss +++ b/scss/custom.scss @@ -610,6 +610,7 @@ ul.compact{ margin: 0; display: block; outline: none; + font-size: 1.1em; } .ui-helper-hidden { -- cgit v1.2.3 From 3c3dc92e3aef6c479b0d5f020c7dc8c4ce76e532 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Sun, 2 Dec 2018 14:15:05 +0100 Subject: Sheet quick actions to add treatments from find, basket and container --- archaeological_finds/models_finds.py | 8 + .../templates/ishtar/sheet_treatment.html | 2 + archaeological_finds/urls.py | 9 + archaeological_finds/views.py | 281 ++++++++++++--------- archaeological_finds/wizards.py | 2 +- archaeological_warehouse/models.py | 17 +- archaeological_warehouse/urls.py | 5 + archaeological_warehouse/views.py | 13 +- ishtar_common/wizards.py | 54 ++-- 9 files changed, 248 insertions(+), 143 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 5dc8abc98..ee6253109 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -616,6 +616,12 @@ class FindBasket(Basket, MainItem): _(u"Manage basket"), "fa fa-shopping-basket", "", "", False), ] + can_edit_find = self.can_do(request, 'change_find') + if can_edit_find: + actions += [ + (reverse('findbasket-add-treatment', args=[self.pk]), + _(u"Add treatment"), "fa fa-exchange", "", "", False), + ] duplicate = self.QUICK_ACTIONS[0] actions += [ @@ -1237,6 +1243,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, (reverse("find-qa-basket", args=[self.pk]), _(u"Add to basket"), "fa fa-shopping-basket", "", "", True), + (reverse('find-add-treatment', args=[self.pk]), + _(u"Add treatment"), "fa fa-exchange", "", "", False), ] if get_current_profile().warehouse: actions.append( diff --git a/archaeological_finds/templates/ishtar/sheet_treatment.html b/archaeological_finds/templates/ishtar/sheet_treatment.html index ced305798..78460d002 100644 --- a/archaeological_finds/templates/ishtar/sheet_treatment.html +++ b/archaeological_finds/templates/ishtar/sheet_treatment.html @@ -109,8 +109,10 @@ {% dynamic_table_document finds 'finds_for_treatment' 'upstream_treatment' item.pk 'TABLE_COLS_FOR_OPE' output %} {% endif %} + {% comment %} {% trans "Related operations" as related_operations %} {% dynamic_table_document related_operations 'operations' 'related_treatment' item.pk 'TABLE_COLS' output %} + {% endcomment %} diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index c5a0f7aa2..cf3522d43 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -89,6 +89,15 @@ urlpatterns = [ views.QAFindbasketDuplicateFormView.as_view()), name='findbasket-qa-duplicate'), + url(r'^findbasket-add-treatment/(?P[0-9-]+)/$', + check_rights(['change_find', 'change_own_find'])( + views.findbasket_treatment_add), + name='findbasket-add-treatment'), + url(r'^find-add-treatment/(?P[0-9-]+)/$', + check_rights(['change_find', 'change_own_find'])( + views.find_treatment_add), + name='find-add-treatment'), + url(r'^find-qa-bulk-update/(?P[0-9-]+)?/$', check_rights(['change_find', 'change_own_find'])( views.QAFindForm.as_view()), diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 81b032d0b..620f33ef4 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -19,6 +19,7 @@ import json +from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.db.models import Q from django.http import HttpResponseRedirect, HttpResponse, Http404 @@ -27,18 +28,24 @@ from django.utils.translation import ugettext_lazy as _ from django.views.generic import TemplateView from django.views.generic.edit import CreateView, FormView + +from ishtar_common.models import IshtarUser, get_current_profile +from archaeological_operations.models import AdministrativeAct +from archaeological_finds import models + +from ishtar_common.forms import FinalForm from archaeological_context_records.forms \ import RecordFormSelection as RecordFormSelectionTable from archaeological_operations.forms import FinalAdministrativeActDeleteForm -from archaeological_operations.wizards import AdministrativeActDeletionWizard -from forms import * -from ishtar_common.forms import FinalForm -from ishtar_common.models import IshtarUser, get_current_profile +from archaeological_finds import forms + from ishtar_common.views import get_autocomplete_generic, IshtarMixin, \ LoginRequiredMixin, QAItemEditForm, QAItemForm from ishtar_common.views_item import display_item, get_item, show_item, \ revert_item, get_autocomplete_item, get_autocomplete_query -from wizards import * + +from archaeological_operations.wizards import AdministrativeActDeletionWizard +from archaeological_finds import wizards get_find = get_item(models.Find, 'get_find', 'find') @@ -141,16 +148,17 @@ get_find_basket_for_write = get_item( model_for_perms=models.Find, alt_query_own='get_write_query_owns' ) -basket_search_wizard = FindBasketSearch.as_view( - [('selec-find_basket_search', FindBasketFormSelection)], +basket_search_wizard = wizards.FindBasketSearch.as_view( + [('selec-find_basket_search', forms.FindBasketFormSelection)], label=_(u"Basket search"), url_name='find_basket_search', ) -basket_modify_wizard = FindBasketEditWizard.as_view( +basket_modify_wizard = wizards.FindBasketEditWizard.as_view( [ - ('selec-find_basket_modification', FindBasketForWriteFormSelection), - ('basket-find_basket_modification', FindBasketForm), + ('selec-find_basket_modification', + forms.FindBasketForWriteFormSelection), + ('basket-find_basket_modification', forms.FindBasketForm), ('final-find_basket_modification', FinalForm) ], label=_(u"Basket modify"), @@ -161,7 +169,7 @@ basket_modify_wizard = FindBasketEditWizard.as_view( def find_basket_modify(request, pk): basket_modify_wizard(request) key = 'selec-find_basket_modification' - FindBasketEditWizard.session_set_value( + wizards.FindBasketEditWizard.session_set_value( request, key, 'pk', pk, reset=True) return redirect( reverse('find_basket_modification', @@ -169,12 +177,12 @@ def find_basket_modify(request, pk): findbasket_deletion_steps = [ - ('selec-find_basket_deletion', FindBasketForWriteFormSelection), + ('selec-find_basket_deletion', forms.FindBasketForWriteFormSelection), ('final-find_basket_deletion', FinalForm) ] -basket_delete_wizard = FindBasketDeletionWizard.as_view( +basket_delete_wizard = wizards.FindBasketDeletionWizard.as_view( findbasket_deletion_steps, label=_(u"Basket deletion"), url_name='find_basket_deletion', @@ -195,9 +203,9 @@ def check_not_warehouse_module(self): find_creation_steps = [ ('selecrecord-find_creation', RecordFormSelectionTable), - ('find-find_creation', FindForm), - ('preservation-find_creation', PreservationForm), - ('dating-find_creation', DatingFormSet), + ('find-find_creation', forms.FindForm), + ('preservation-find_creation', forms.PreservationForm), + ('dating-find_creation', forms.DatingFormSet), ('final-find_creation', FinalForm) ] @@ -205,7 +213,7 @@ find_creation_condition_dict = { 'preservation-find_creation': check_preservation_module, } -find_creation_wizard = FindWizard.as_view( +find_creation_wizard = wizards.FindWizard.as_view( find_creation_steps, label=_(u"New find"), condition_dict=find_creation_condition_dict, @@ -216,9 +224,9 @@ find_search_condition_dict = { 'generalwarehouse-find_search': check_warehouse_module, } -find_search_wizard = FindSearch.as_view([ - ('general-find_search', FindFormSelection), - ('generalwarehouse-find_search', FindFormSelectionWarehouseModule)], +find_search_wizard = wizards.FindSearch.as_view([ + ('general-find_search', forms.FindFormSelection), + ('generalwarehouse-find_search', forms.FindFormSelectionWarehouseModule)], label=_(u"Find search"), url_name='find_search', condition_dict=find_search_condition_dict @@ -246,17 +254,17 @@ find_modification_condition_dict = { } find_modification_steps = [ - ('selec-find_modification', FindFormSelection), - ('selecw-find_modification', FindFormSelectionWarehouseModule), - ('selecrecord-find_modification', RecordFormSelection), - ('find-find_modification', FindForm), - ('simplefind-find_modification', SimpleFindForm), - ('preservation-find_modification', PreservationForm), - ('dating-find_modification', DatingFormSet), + ('selec-find_modification', forms.FindFormSelection), + ('selecw-find_modification', forms.FindFormSelectionWarehouseModule), + ('selecrecord-find_modification', forms.RecordFormSelection), + ('find-find_modification', forms.FindForm), + ('simplefind-find_modification', forms.SimpleFindForm), + ('preservation-find_modification', forms.PreservationForm), + ('dating-find_modification', forms.DatingFormSet), ('final-find_modification', FinalForm) ] -find_modification_wizard = FindModificationWizard.as_view( +find_modification_wizard = wizards.FindModificationWizard.as_view( find_modification_steps, condition_dict=find_modification_condition_dict, label=_(u"Find modification"), @@ -269,7 +277,7 @@ def find_modify(request, pk): key = 'selec-find_modification' if get_current_profile().warehouse: key = 'selecw-find_modification' - FindModificationWizard.session_set_value( + wizards.FindModificationWizard.session_set_value( request, key, 'pk', pk, reset=True) q = models.Find.objects.filter(pk=pk) if not q.count(): @@ -287,11 +295,11 @@ find_deletion_condition_dict = { } find_deletion_steps = [ - ('selec-find_deletion', FindFormSelection), - ('selecw-find_deletion', FindFormSelectionWarehouseModule), - ('final-find_deletion', FindDeletionForm)] + ('selec-find_deletion', forms.FindFormSelection), + ('selecw-find_deletion', forms.FindFormSelectionWarehouseModule), + ('final-find_deletion', forms.FindDeletionForm)] -find_deletion_wizard = FindDeletionWizard.as_view( +find_deletion_wizard = wizards.FindDeletionWizard.as_view( find_deletion_steps, condition_dict=find_deletion_condition_dict, label=_(u"Find deletion"), @@ -306,7 +314,7 @@ autocomplete_integritytype = get_autocomplete_generic(models.IntegrityType) class NewFindBasketView(IshtarMixin, LoginRequiredMixin, CreateView): template_name = 'ishtar/form.html' model = models.FindBasket - form_class = NewFindBasketForm + form_class = forms.NewFindBasketForm page_name = _(u"New basket") def get_form_kwargs(self): @@ -335,7 +343,7 @@ class OwnBasket(object): class SelectBasketForManagement(IshtarMixin, LoginRequiredMixin, FormView): template_name = 'ishtar/form.html' - form_class = SelectFindBasketForm + form_class = forms.SelectFindBasketForm page_name = _(u"Manage items in basket") def get_form_kwargs(self): @@ -368,9 +376,9 @@ class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin, ) context['basket'] = self.basket if get_current_profile().warehouse: - context['form'] = MultipleFindFormSelectionWarehouseModule() + context['form'] = forms.MultipleFindFormSelectionWarehouseModule() else: - context['form'] = MultipleFindFormSelection() + context['form'] = forms.MultipleFindFormSelection() context['add_url'] = reverse('add_iteminbasket') context['list_url'] = reverse('list_iteminbasket', kwargs={'pk': self.basket.pk}) @@ -382,7 +390,7 @@ class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin, class FindBasketAddItemView(IshtarMixin, LoginRequiredMixin, FormView): template_name = 'ishtar/simple_form.html' - form_class = FindBasketAddItemForm + form_class = forms.FindBasketAddItemForm def get_success_url(self, basket): return reverse('list_iteminbasket', kwargs={'pk': basket.pk}) @@ -448,53 +456,53 @@ get_downstreamtreatment = get_item( 'downtreatment') treatment_wizard_steps = [ - ('selecfind-treatment_creation', UpstreamFindFormSelection), - ('file-treatment_creation', TreatmentFormFileChoice), - ('basetreatment-treatment_creation', BaseTreatmentForm), + ('selecfind-treatment_creation', forms.UpstreamFindFormSelection), + ('file-treatment_creation', forms.TreatmentFormFileChoice), + ('basetreatment-treatment_creation', forms.BaseTreatmentForm), ('final-treatment_creation', FinalForm) ] -treatment_search_wizard = TreatmentSearch.as_view([ - ('general-treatment_search', TreatmentFormSelection)], +treatment_search_wizard = wizards.TreatmentSearch.as_view([ + ('general-treatment_search', forms.TreatmentFormSelection)], label=_(u"Treatment search"), url_name='treatment_search',) -treatment_creation_wizard = TreatmentWizard.as_view( +treatment_creation_wizard = wizards.TreatmentWizard.as_view( treatment_wizard_steps, label=_(u"New treatment"), url_name='treatment_creation',) treatment_n1_wizard_steps = [ - ('selecfind-treatment_creation_n1', UpstreamFindFormSelection), - ('file-treatment_creation_n1', TreatmentFormFileChoice), - ('basetreatment-treatment_creation_n1', N1TreatmentForm), - ('resultingfind-treatment_creation_n1', ResultingFindForm), + ('selecfind-treatment_creation_n1', forms.UpstreamFindFormSelection), + ('file-treatment_creation_n1', forms.TreatmentFormFileChoice), + ('basetreatment-treatment_creation_n1', forms.N1TreatmentForm), + ('resultingfind-treatment_creation_n1', forms.ResultingFindForm), ('final-treatment_creation_n1', FinalForm) ] -treatment_creation_n1_wizard = TreatmentN1Wizard.as_view( +treatment_creation_n1_wizard = wizards.TreatmentN1Wizard.as_view( treatment_n1_wizard_steps, label=_(u"New treatment"), url_name='treatment_creation_n1',) treatment_1n_wizard_steps = [ - ('selecfind-treatment_creation_1n', SingleUpstreamFindFormSelection), - ('file-treatment_creation_1n', TreatmentFormFileChoice), - ('basetreatment-treatment_creation_1n', OneNTreatmentForm), - ('resultingfinds-treatment_creation_1n', ResultingFindsForm), + ('selecfind-treatment_creation_1n', forms.SingleUpstreamFindFormSelection), + ('file-treatment_creation_1n', forms.TreatmentFormFileChoice), + ('basetreatment-treatment_creation_1n', forms.OneNTreatmentForm), + ('resultingfinds-treatment_creation_1n', forms.ResultingFindsForm), ('final-treatment_creation_1n', FinalForm) ] -treatment_creation_1n_wizard = Treatment1NWizard.as_view( +treatment_creation_1n_wizard = wizards.Treatment1NWizard.as_view( treatment_1n_wizard_steps, label=_(u"New treatment"), url_name='treatment_creation_1n',) -treatment_modification_wizard = TreatmentModificationWizard.as_view( - [('selec-treatment_modification', TreatmentFormSelection), - ('file-treatment_modification', TreatmentFormFileChoice), - ('basetreatment-treatment_modification', TreatmentModifyForm), +treatment_modification_wizard = wizards.TreatmentModificationWizard.as_view( + [('selec-treatment_modification', forms.TreatmentFormSelection), + ('file-treatment_modification', forms.TreatmentFormFileChoice), + ('basetreatment-treatment_modification', forms.TreatmentModifyForm), ('final-treatment_modification', FinalForm)], label=_(u"Treatment modification"), url_name='treatment_modification', @@ -503,41 +511,77 @@ treatment_modification_wizard = TreatmentModificationWizard.as_view( def treatment_modify(request, pk): treatment_modification_wizard(request) - TreatmentModificationWizard.session_set_value( + wizards.TreatmentModificationWizard.session_set_value( request, 'selec-treatment_modification', 'pk', pk, reset=True) return redirect(reverse( 'treatment_modification', kwargs={'step': 'basetreatment-treatment_modification'})) -treatment_deletion_wizard = TreatmentDeletionWizard.as_view([ - ('selec-treatment_deletion', TreatmentFormSelection), - ('final-treatment_deletion', TreatmentDeletionForm)], +def treatment_add(request, pks): + treatment_creation_wizard(request) + wizards.TreatmentWizard.session_set_value( + request, 'selecfind-treatment_creation', + 'resulting_pk', pks, reset=True) + wizards.TreatmentWizard.session_set_value( + request, 'file-treatment_creation', 'file', '') + return redirect(reverse( + 'treatment_creation', + kwargs={'step': 'basetreatment-treatment_creation'})) + + +def find_treatment_add(request, pk, current_right=None): + if not models.Find.objects.filter(pk=pk).count(): + raise Http404() + return treatment_add(request, str(pk)) + + +def findbasket_treatment_add(request, pk, current_right=None): + try: + basket = models.FindBasket.objects.get(pk=pk) + except models.FindBasket.DoesNotExist: + raise Http404() + return treatment_add( + request, ",".join([str(f.pk) for f in basket.items.all()])) + + +def container_treatment_add(request, pk, current_right=None): + try: + basket = models.FindBasket.objects.get(pk=pk) + except models.FindBasket.DoesNotExist: + raise Http404() + return treatment_add(request, + ",".join([str(f.pk) for f in basket.items.all()])) + + +treatment_deletion_wizard = wizards.TreatmentDeletionWizard.as_view([ + ('selec-treatment_deletion', forms.TreatmentFormSelection), + ('final-treatment_deletion', forms.TreatmentDeletionForm)], label=_(u"Treatment deletion"), url_name='treatment_deletion',) treatment_administrativeact_search_wizard = \ - SearchWizard.as_view([ + wizards.SearchWizard.as_view([ ('selec-treatment_admacttreatment_search', - AdministrativeActTreatmentFormSelection)], + forms.AdministrativeActTreatmentFormSelection)], label=_(u"Treatment: search administrative act"), url_name='treatment_admacttreatment_search',) treatment_administrativeact_wizard = \ - TreatmentAdministrativeActWizard.as_view([ - ('selec-treatment_admacttreatment', TreatmentFormSelection), + wizards.TreatmentAdministrativeActWizard.as_view([ + ('selec-treatment_admacttreatment', forms.TreatmentFormSelection), ('administrativeact-treatment_admacttreatment', - AdministrativeActTreatmentForm), + forms.AdministrativeActTreatmentForm), ('final-treatment_admacttreatment', FinalForm)], label=_(u"Treatment: new administrative act"), url_name='treatment_admacttreatment',) treatment_administrativeact_modification_wizard = \ - TreatmentEditAdministrativeActWizard.as_view([ + wizards.TreatmentEditAdministrativeActWizard.as_view([ ('selec-treatment_admacttreatment_modification', - AdministrativeActTreatmentFormSelection), + forms.AdministrativeActTreatmentFormSelection), ('administrativeact-treatment_admacttreatment_modification', - AdministrativeActTreatmentModifForm), + forms.AdministrativeActTreatmentModifForm), ('final-treatment_admacttreatment_modification', FinalForm)], label=_(u"Treatment: administrative act modification"), url_name='treatment_admacttreatment_modification',) @@ -545,7 +589,7 @@ treatment_administrativeact_modification_wizard = \ treatment_admacttreatment_deletion_wizard = \ AdministrativeActDeletionWizard.as_view([ ('selec-treatment_admacttreatment_deletion', - AdministrativeActTreatmentFormSelection), + forms.AdministrativeActTreatmentFormSelection), ('final-treatment_admacttreatment_deletion', FinalAdministrativeActDeleteForm)], label=_(u"Treatment: administrative act deletion"), @@ -554,7 +598,7 @@ treatment_admacttreatment_deletion_wizard = \ def treatment_administrativeacttreatment_modify(request, pk): treatment_administrativeact_modification_wizard(request) - TreatmentEditAdministrativeActWizard.session_set_value( + wizards.TreatmentEditAdministrativeActWizard.session_set_value( request, 'selec-treatment_admacttreatment_modification', 'pk', pk, reset=True) @@ -569,67 +613,70 @@ def treatment_administrativeacttreatment_modify(request, pk): # treatment request -treatmentfile_search_wizard = TreatmentFileSearch.as_view([ - ('general-treatmentfile_search', TreatmentFileFormSelection)], +treatmentfile_search_wizard = wizards.TreatmentFileSearch.as_view([ + ('general-treatmentfile_search', forms.TreatmentFileFormSelection)], label=_(u"Treatment request search"), url_name='treatmentfile_search',) treatmentfile_wizard_steps = [ - ('treatmentfile-treatmentfile_creation', TreatmentFileForm), + ('treatmentfile-treatmentfile_creation', forms.TreatmentFileForm), ('final-treatmentfile_creation', FinalForm)] -treatmentfile_creation_wizard = TreatmentFileWizard.as_view( +treatmentfile_creation_wizard = wizards.TreatmentFileWizard.as_view( treatmentfile_wizard_steps, label=_(u"New treatment request"), url_name='treatmentfile_creation',) -treatmentfile_modification_wizard = TreatmentFileModificationWizard.as_view( - [('selec-treatmentfile_modification', TreatmentFileFormSelection), - ('treatmentfile-treatmentfile_modification', TreatmentFileModifyForm), - ('final-treatmentfile_modification', FinalForm)], - label=_(u"Treatment request modification"), - url_name='treatmentfile_modification', -) +treatmentfile_modification_wizard = \ + wizards.TreatmentFileModificationWizard.as_view( + [('selec-treatmentfile_modification', forms.TreatmentFileFormSelection), + ('treatmentfile-treatmentfile_modification', + forms.TreatmentFileModifyForm), + ('final-treatmentfile_modification', FinalForm)], + label=_(u"Treatment request modification"), + url_name='treatmentfile_modification', + ) def treatmentfile_modify(request, pk): treatmentfile_modification_wizard(request) - TreatmentFileModificationWizard.session_set_value( + wizards.TreatmentFileModificationWizard.session_set_value( request, 'selec-treatmentfile_modification', 'pk', pk, reset=True) return redirect(reverse( 'treatmentfile_modification', kwargs={'step': 'treatmentfile-treatmentfile_modification'})) -treatmentfile_deletion_wizard = TreatmentFileDeletionWizard.as_view([ - ('selec-treatmentfile_deletion', TreatmentFileFormSelection), - ('final-treatmentfile_deletion', TreatmentFileDeletionForm)], +treatmentfile_deletion_wizard = wizards.TreatmentFileDeletionWizard.as_view([ + ('selec-treatmentfile_deletion', forms.TreatmentFileFormSelection), + ('final-treatmentfile_deletion', forms.TreatmentFileDeletionForm)], label=_(u"Treatment request deletion"), url_name='treatmentfile_deletion',) treatmentfile_admacttreatmentfile_search_wizard = \ - SearchWizard.as_view([ + wizards.SearchWizard.as_view([ ('selec-treatmentfle_admacttreatmentfle_search', - AdministrativeActTreatmentFileFormSelection)], + forms.AdministrativeActTreatmentFileFormSelection)], label=_(u"Treatment request: search administrative act"), url_name='treatmentfle_admacttreatmentfle_search',) treatmentfile_admacttreatmentfile_wizard = \ - TreatmentFileAdministrativeActWizard.as_view([ - ('selec-treatmentfle_admacttreatmentfle', TreatmentFileFormSelection), + wizards.TreatmentFileAdministrativeActWizard.as_view([ + ('selec-treatmentfle_admacttreatmentfle', + forms.TreatmentFileFormSelection), ('admact-treatmentfle_admacttreatmentfle', - AdministrativeActTreatmentFileForm), + forms.AdministrativeActTreatmentFileForm), ('final-treatmentfle_admacttreatmentfle', FinalForm)], label=_(u"Treatment request: new administrative act"), url_name='treatmentfle_admacttreatmentfle',) treatmentfile_admacttreatmentfile_modification_wizard = \ - TreatmentFileEditAdministrativeActWizard.as_view([ + wizards.TreatmentFileEditAdministrativeActWizard.as_view([ ('selec-treatmentfle_admacttreatmentfle_modification', - AdministrativeActTreatmentFileFormSelection), + forms.AdministrativeActTreatmentFileFormSelection), ('admact-treatmentfle_admacttreatmentfle_modification', - AdministrativeActTreatmentFileModifForm), + forms.AdministrativeActTreatmentFileModifForm), ('final-treatmentfle_admacttreatmentfle_modification', FinalForm)], label=_(u"Treatment request: administrative act modification"), url_name='treatmentfle_admacttreatmentfle_modification',) @@ -637,7 +684,7 @@ treatmentfile_admacttreatmentfile_modification_wizard = \ treatmentfile_admacttreatmentfile_deletion_wizard = \ AdministrativeActDeletionWizard.as_view([ ('selec-treatmentfle_admacttreatmentfle_deletion', - AdministrativeActTreatmentFileFormSelection), + forms.AdministrativeActTreatmentFileFormSelection), ('final-treatmentfle_admacttreatmentfle_deletion', FinalAdministrativeActDeleteForm)], label=_(u"Treatment request: administrative act deletion"), @@ -646,7 +693,7 @@ treatmentfile_admacttreatmentfile_deletion_wizard = \ def treatmentfile_administrativeacttreatmentfile_modify(request, pk): treatmentfile_admacttreatmentfile_modification_wizard(request) - TreatmentFileEditAdministrativeActWizard.session_set_value( + wizards.TreatmentFileEditAdministrativeActWizard.session_set_value( request, 'selec-treatmentfle_admacttreatmentfle_modification', 'pk', pk, reset=True) @@ -661,22 +708,26 @@ def treatmentfile_administrativeacttreatmentfile_modify(request, pk): def reset_wizards(request): for wizard_class, url_name in ( - (FindWizard, 'find_creation'), - (FindModificationWizard, 'find_modification'), - (FindDeletionWizard, 'find_deletion'), - (TreatmentWizard, 'treatement_creation'), - (TreatmentModificationWizard, 'treatment_modification'), - (TreatmentDeletionWizard, 'treatment_deletion'), - (TreatmentAdministrativeActWizard, 'treatment_admacttreatment'), - (TreatmentEditAdministrativeActWizard, + (wizards.FindWizard, 'find_creation'), + (wizards.FindModificationWizard, 'find_modification'), + (wizards.FindDeletionWizard, 'find_deletion'), + (wizards.TreatmentWizard, 'treatement_creation'), + (wizards.TreatmentModificationWizard, 'treatment_modification'), + (wizards.TreatmentDeletionWizard, 'treatment_deletion'), + (wizards.TreatmentAdministrativeActWizard, + 'treatment_admacttreatment'), + (wizards.TreatmentEditAdministrativeActWizard, 'treatment_admacttreatment_modification'), - (TreatmentDeletionWizard, 'treatment_admacttreatment_deletion'), - (TreatmentFileWizard, 'treatmentfile_creation'), - (TreatmentFileModificationWizard, 'treatmentfile_modification'), - (TreatmentFileDeletionWizard, 'treatmentfile_deletion'), - (TreatmentFileAdministrativeActWizard, + (wizards.TreatmentDeletionWizard, + 'treatment_admacttreatment_deletion'), + (wizards.TreatmentFileWizard, + 'treatmentfile_creation'), + (wizards.TreatmentFileModificationWizard, + 'treatmentfile_modification'), + (wizards.TreatmentFileDeletionWizard, 'treatmentfile_deletion'), + (wizards.TreatmentFileAdministrativeActWizard, 'treatmentfle_admacttreatmentfle'), - (TreatmentFileEditAdministrativeActWizard, + (wizards.TreatmentFileEditAdministrativeActWizard, 'treatmentfle_admacttreatmentfle_modification'), (AdministrativeActDeletionWizard, 'treatmentfle_admacttreatmentfle_deletion'), @@ -686,13 +737,13 @@ def reset_wizards(request): class QAFindForm(QAItemEditForm): model = models.Find - form_class = QAFindFormMulti + form_class = forms.QAFindFormMulti class QAFindBasketFormView(QAItemForm): template_name = 'ishtar/forms/qa_find_basket.html' model = models.Find - form_class = QAFindBasketForm + form_class = forms.QAFindBasketForm page_name = _(u"Basket") modal_size = "small" @@ -712,7 +763,7 @@ class QAFindBasketFormView(QAItemForm): class QAFindTreatmentFormView(QAItemForm): template_name = 'ishtar/forms/qa_find_treatment.html' model = models.Find - form_class = QAFindTreatmentForm + form_class = forms.QAFindTreatmentForm page_name = _(u"Packaging") def get_quick_action(self): @@ -734,7 +785,7 @@ class QAFindbasketDuplicateFormView(QAItemForm): model = models.FindBasket page_name = _(u"Duplicate") modal_size = "small" - form_class = QAFindbasketDuplicateForm + form_class = forms.QAFindbasketDuplicateForm def get_quick_action(self): return models.FindBasket.QUICK_ACTIONS[0] diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index 31881fe74..d523170eb 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -138,7 +138,7 @@ class TreatmentBase(Wizard): models.Find.objects.get(pk=int(find_id.strip())) for find_id in find_ids.split(u',') ] - except(TypeError, ValueError, ObjectDoesNotExist): + except(TypeError, ValueError, AttributeError, ObjectDoesNotExist): pass def get_form_initial(self, step, data=None): diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 5565bc504..92eaf5d2f 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -21,6 +21,7 @@ import datetime from django.conf import settings from django.contrib.gis.db import models +from django.core.urlresolvers import reverse from django.db.models import Q from django.db.models.signals import post_save, post_delete from django.template.defaultfilters import slugify @@ -311,7 +312,7 @@ post_save.connect(post_save_cache, sender=ContainerType) post_delete.connect(post_save_cache, sender=ContainerType) -class Container(LightHistorizedItem, ImageModel): +class Container(LightHistorizedItem, ImageModel, OwnPerms): TABLE_COLS = ['reference', 'container_type__label', 'cached_location', 'cached_division', 'old_reference'] IMAGE_PREFIX = 'containers/' @@ -570,6 +571,20 @@ class Container(LightHistorizedItem, ImageModel): def set_localisation_9(self, context, value): return self.set_localisation(8, value) + def get_extra_actions(self, request): + """ + extra actions for the sheet template + """ + # url, base_text, icon, extra_text, extra css class, is a quick action + actions = [] + can_edit_find = self.can_do(request, 'change_find') + if can_edit_find: + actions += [ + (reverse('container-add-treatment', args=[self.pk]), + _(u"Add treatment"), "fa fa-exchange", "", "", False), + ] + return actions + def pre_save(self): if not self.index: q = Container.objects.filter(responsible=self.responsible).order_by( diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py index 5dce12ffa..47058a352 100644 --- a/archaeological_warehouse/urls.py +++ b/archaeological_warehouse/urls.py @@ -68,6 +68,11 @@ urlpatterns = [ url(r'warehouse-modify/(?P.+)/$', views.warehouse_modify, name='warehouse_modify'), + url(r'^container-add-treatment/(?P[0-9-]+)/$', + check_rights(['change_find', 'change_own_find'])( + views.container_treatment_add), + name='container-add-treatment'), + url(r'^container_search/(?P.+)?$', check_rights(['view_container', 'view_own_container'])( views.container_search_wizard), diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index 0cd68dac6..83fd7f4e1 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -21,7 +21,7 @@ import json from django.core.urlresolvers import reverse from django.db.models import Q -from django.http import HttpResponse +from django.http import HttpResponse, Http404 from django.shortcuts import redirect from django.utils.translation import ugettext_lazy as _ @@ -35,6 +35,8 @@ from archaeological_warehouse.forms import WarehouseForm, ContainerForm, \ from ishtar_common.forms import FinalForm from ishtar_common.views_item import get_item, show_item, new_item +from archaeological_finds.views import treatment_add + from archaeological_warehouse.wizards import PackagingWizard, WarehouseSearch, \ WarehouseWizard, WarehouseModificationWizard, WarehouseDeletionWizard, \ ContainerSearch, ContainerWizard, ContainerModificationWizard, \ @@ -195,6 +197,15 @@ container_deletion_wizard = ContainerDeletionWizard.as_view([ label=_(u"Container deletion"), url_name='container_deletion',) + +def container_treatment_add(request, pk, current_right=None): + try: + container = models.Container.objects.get(pk=pk) + except models.Container.DoesNotExist: + raise Http404() + return treatment_add( + request, ",".join([str(f.pk) for f in container.finds.all()])) + """ warehouse_packaging_wizard = ItemSourceWizard.as_view([ ('selec-warehouse_packaging', ItemsSelection), diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 19eb312e1..446afc71e 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -147,36 +147,40 @@ class Wizard(IshtarWizard): form, other_check) return kwargs + def check_own_permissions(self, request, step, *args, **kwargs): + # reinit default dispatch of a wizard - not clean... + self.request = request + self.session = request.session + self.prefix = self.get_prefix(request, *args, **kwargs) + self.storage = get_storage( + self.storage_name, self.prefix, request, + getattr(self, 'file_storage', None)) + self.steps = StepsHelper(self) + + current_object = self.get_current_object() + ishtaruser = request.user.ishtaruser \ + if hasattr(request.user, 'ishtaruser') else None + + # not the first step and current object is not owned + if self.steps and self.steps.first != step and current_object: + is_own = current_object.is_own( + ishtaruser, alt_query_own=self.alt_is_own_method) + if not is_own: + messages.add_message( + request, messages.WARNING, + _(u"Permission error: you cannot do this action.") + ) + self.session_reset(request, self.url_name) + return + return True + def dispatch(self, request, *args, **kwargs): self.current_right = kwargs.get('current_right', None) step = kwargs.get('step', None) # check that the current object is really owned by the current user if step and self.current_right and '_own_' in self.current_right: - - # reinit default dispatch of a wizard - not clean... - self.request = request - self.session = request.session - self.prefix = self.get_prefix(request, *args, **kwargs) - self.storage = get_storage( - self.storage_name, self.prefix, request, - getattr(self, 'file_storage', None)) - self.steps = StepsHelper(self) - - current_object = self.get_current_object() - ishtaruser = request.user.ishtaruser \ - if hasattr(request.user, 'ishtaruser') else None - - # not the first step and current object is not owned - if self.steps and self.steps.first != step and current_object: - is_own = current_object.is_own( - ishtaruser, alt_query_own=self.alt_is_own_method) - if not is_own: - messages.add_message( - request, messages.WARNING, - _(u"Permission error: you cannot do this action.") - ) - self.session_reset(request, self.url_name) - return HttpResponseRedirect('/') + if not self.check_permissions(request, step, *args, **kwargs): + return HttpResponseRedirect('/') # extra filter on forms self.filter_owns_items = True else: -- cgit v1.2.3 From 97f43cba1ba5204f2da685c04aed5770ff3d68a8 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 4 Dec 2018 11:15:44 +0100 Subject: Fix wizard permissions call --- ishtar_common/forms.py | 7 +++++-- ishtar_common/wizards.py | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'ishtar_common/wizards.py') diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 0c93016b1..b27d4cf4d 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -745,8 +745,11 @@ class QAForm(CustomForm, ManageOldType): elif hasattr(self.fields[k], "choices"): values = [] for v in kwargs['data'].getlist(k): - values.append( - dict(self.fields[k].choices)[int(v)]) + dct_choices = dict(self.fields[k].choices) + if v in dct_choices: + values.append(dct_choices[v]) + elif int(v) in dct_choices: + values.append(dct_choices[int(v)]) self.fields[k].rendered_value = mark_safe( u" ; ".join(values)) if k not in self.REPLACE_FIELDS: diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 446afc71e..47355dd06 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -147,7 +147,7 @@ class Wizard(IshtarWizard): form, other_check) return kwargs - def check_own_permissions(self, request, step, *args, **kwargs): + def check_own_permissions(self, request, step=None, *args, **kwargs): # reinit default dispatch of a wizard - not clean... self.request = request self.session = request.session @@ -179,7 +179,7 @@ class Wizard(IshtarWizard): step = kwargs.get('step', None) # check that the current object is really owned by the current user if step and self.current_right and '_own_' in self.current_right: - if not self.check_permissions(request, step, *args, **kwargs): + if not self.check_own_permissions(request, *args, **kwargs): return HttpResponseRedirect('/') # extra filter on forms self.filter_owns_items = True -- cgit v1.2.3