diff options
Diffstat (limited to 'archaeological_finds')
-rw-r--r-- | archaeological_finds/forms.py | 66 | ||||
-rw-r--r-- | archaeological_finds/forms_treatments.py | 16 | ||||
-rw-r--r-- | archaeological_finds/ishtar_menu.py | 7 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 10 | ||||
-rw-r--r-- | archaeological_finds/models_treatments.py | 48 | ||||
-rw-r--r-- | archaeological_finds/urls.py | 3 | ||||
-rw-r--r-- | archaeological_finds/views.py | 13 | ||||
-rw-r--r-- | archaeological_finds/wizards.py | 67 |
8 files changed, 214 insertions, 16 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 970b35f92..b95ac90c6 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -44,7 +44,7 @@ from archaeological_finds.forms_treatments import TreatmentSelect, \ AdministrativeActTreatmentFileFormSelection, \ AdministrativeActTreatmentFileModifForm, \ DashboardForm as DashboardTreatmentForm, N1TreatmentForm,\ - DashboardTreatmentFileForm, QAFindTreatmentForm + DashboardTreatmentFileForm, QAFindTreatmentForm, OneNTreatmentForm from archaeological_operations.models import Period, ArchaeologicalSite, \ RelationType as OpeRelationType from archaeological_operations.widgets import OAWidget @@ -84,7 +84,8 @@ __all__ = [ 'SelectFindBasketForm', 'DeleteFindBasketForm', 'FindBasketAddItemForm', 'QAFindFormSingle', 'QAFindFormMulti', 'QAFindBasketForm', 'QAFindTreatmentForm', - 'N1TreatmentForm', 'ResultingFindForm' + 'N1TreatmentForm', 'OneNTreatmentForm', 'ResultingFindForm', + 'ResultingFindsForm', 'SingleUpstreamFindFormSelection' ] logger = logging.getLogger(__name__) @@ -379,8 +380,8 @@ class SimpleFindForm(BaseFindForm): class ResultingFindForm(CustomForm, ManageOldType): file_upload = True form_label = _("Resulting find") - form_admin_name = _(u"Treatment n-1 - 030 - General") - form_slug = "treatmentn1-030-general" + form_admin_name = _(u"Treatment n-1 - 030 - Resulting find") + form_slug = "treatmentn1-030-resulting-find" associated_models = { 'resulting_material_type': models.MaterialType, @@ -472,6 +473,50 @@ class ResultingFindForm(CustomForm, ManageOldType): ] +class ResultingFindsForm(CustomForm, ManageOldType): + form_label = _("Resulting finds") + form_admin_name = _(u"Treatment 1-n - 030 - Resulting finds") + form_slug = "treatment1n-030-resulting-finds" + associated_models = {} + + resultings_number = forms.IntegerField( + label=_(u"Number of resulting finds"), + min_value=1 + ) + resultings_label = forms.CharField( + label=_(u"Prefix label for resulting finds"), + validators=[validators.MaxLengthValidator(200)], + help_text=_( + u'E.g.: with a prefix "item-", each resulting item will be named ' + u'"item-1", "item-2", "item-3"') + ) + resultings_start_number = forms.IntegerField( + label=_(u"Numbering starting from"), initial=1, min_value=0 + ) + resultings_basket_name = forms.CharField( + label=_(u"Name of the new basket containing the resulting items"), + max_length=200 + ) + + def __init__(self, *args, **kwargs): + self.user = None + if 'user' in kwargs: + self.user = kwargs.pop('user') + if hasattr(self.user, 'ishtaruser'): + self.user = self.user.ishtaruser + super(ResultingFindsForm, self).__init__(*args, **kwargs) + if not self.user: + return + + def clean(self): + q = models.FindBasket.objects.filter( + user=self.user, label=self.cleaned_data['resultings_basket_name']) + if q.count(): + raise forms.ValidationError(_(u"A basket with this label already " + u"exists.")) + return self.cleaned_data + + class QAFindFormMulti(QAForm): form_admin_name = _(u"Find - Quick action - Modify") form_slug = "find-quickaction-modify" @@ -1065,7 +1110,7 @@ class FindDeletionForm(FinalForm): class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection): - form_label = _(u"Upstream find") + form_label = _(u"Upstream finds") current_model = models.Find pk_key = 'resulting_pk' @@ -1084,6 +1129,17 @@ class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection): self.fields['resulting_pk'] = self.fields.pop('pk') +class SingleUpstreamFindFormSelection(UpstreamFindFormSelection): + current_model = models.Find + pk = forms.CharField( + label="", required=False, + widget=widgets.DataTable( + reverse_lazy('get-find'), + FindSelect, current_model, + source_full=reverse_lazy('get-find-full')), + validators=[valid_ids(current_model)]) + + class FindBasketSelect(CustomForm, TableSelect): _model = models.FindBasket diff --git a/archaeological_finds/forms_treatments.py b/archaeological_finds/forms_treatments.py index 99a685825..be53dd418 100644 --- a/archaeological_finds/forms_treatments.py +++ b/archaeological_finds/forms_treatments.py @@ -80,7 +80,7 @@ class TreatmentFormSelection(forms.Form): class BaseTreatmentForm(CustomForm, ManageOldType): - form_label = _(u"Base treatment") + form_label = _(u"Treatment") form_admin_name = _(u"Treatment - 020 - General") form_slug = "treatment-020-general" base_models = ['treatment_type'] @@ -231,7 +231,6 @@ class BaseTreatmentForm(CustomForm, ManageOldType): class N1TreatmentForm(BaseTreatmentForm): - form_label = _(u"Base treatment") form_admin_name = _(u"Treatment n-1 - 020 - General") form_slug = "treatmentn1-020-general" @@ -244,6 +243,19 @@ class N1TreatmentForm(BaseTreatmentForm): ] +class OneNTreatmentForm(BaseTreatmentForm): + form_admin_name = _(u"Treatment 1-n - 020 - General") + form_slug = "treatment1n-020-general" + + TYPES = [ + FieldType('treatment_state', models.TreatmentState), + FieldType( + 'treatment_type', models.TreatmentType, is_multiple=True, + extra_args={'dct': {'upstream_is_many': False, + 'downstream_is_many': True}}) + ] + + class TreatmentModifyForm(BaseTreatmentForm): index = forms.IntegerField(_(u"Index")) id = forms.IntegerField(' ', widget=forms.HiddenInput, required=False) diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py index cd7ed19b7..2f37f4c4b 100644 --- a/archaeological_finds/ishtar_menu.py +++ b/archaeological_finds/ishtar_menu.py @@ -167,6 +167,13 @@ MENU_SECTIONS = [ u"- creation"), model=models.Treatment, access_controls=['change_find', 'change_own_find']), + MenuItem( + 'treatment_creation_1n', + _(u"Treatment " + u"1 <i class='fa fa-arrows-h' aria-hidden='true'></i> n " + u"- creation"), + model=models.Treatment, + access_controls=['change_find', 'change_own_find']), MenuItem('treatment_modification', _(u"Modification"), model=models.Treatment, diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 1fb4f6132..e856cb8ca 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1348,7 +1348,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, q = q.filter(**fltr) return q.filter(downstream_treatment__isnull=True).count() - def duplicate(self, user): + def duplicate(self, user, copy_datings=True): model = self.__class__ new = model.objects.get(pk=self.pk) @@ -1366,9 +1366,11 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, m2m = [field.name for field in model._meta.many_to_many if field.name not in PRIVATE_FIELDS] for field in m2m: - if field == 'images': - for doc in Document.objects.filter(finds__pk=self.pk).all(): - doc.finds.add(new.pk) + if field == 'datings' and copy_datings: + for dating in self.datings.all(): + dating.pk = None + dating.save() + new.datings.add(dating) else: for val in getattr(self, field).all(): getattr(new, field).add(val) diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index d92c98235..68935f142 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -29,6 +29,7 @@ from django.utils.translation import ugettext_lazy as _, pgettext_lazy, \ from archaeological_finds.models_finds import Find, FindBasket, TreatmentType from archaeological_operations.models import ClosedItem, Operation +from archaeological_context_records.models import Dating from archaeological_warehouse.models import Warehouse, Container from ishtar_common.models import Document, GeneralType, \ ImageModel, BaseHistorizedItem, OwnPerms, HistoricalRecords, Person, \ @@ -72,7 +73,8 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, "person__cached_label": _(u"Responsible"), } # extra keys than can be passed to save method - EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items') + EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items', + 'resulting_finds', 'upstream_item') # alternative names of fields for searches ALT_NAMES = { @@ -293,7 +295,10 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, if q.count(): self.index = q.all().aggregate(Max('index'))['index__max'] + 1 - def _create_resulting_find(self, resulting_find, upstream_items): + def _create_n_1_resulting_find(self, resulting_find, upstream_items): + """ + Manage creation of n<->1 treatment + """ m2m = {} base_fields = [f.name for f in Find._meta.get_fields()] for k in resulting_find.keys(): @@ -363,15 +368,45 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, new_find.skip_history_when_saving = True new_find.save() + def _create_1_n_resulting_find(self, resulting_finds, upstream_item, user): + """ + Manage creation of 1<->n treatment + """ + new_items = [] + start_number = resulting_finds['start_number'] + for idx in range(resulting_finds['number']): + label = resulting_finds['label'] + unicode(start_number + idx) + new_find = Find.objects.get( + pk=upstream_item.pk).duplicate(user) + new_find.upstream_treatment = self + new_find.label = label + new_find.skip_history_when_saving = True + new_find.save() + new_items.append(new_find) + + upstream_item.downstream_treatment = self + upstream_item.skip_history_when_saving = True + upstream_item.save() + + if getattr(user, 'ishtaruser', None): + b = FindBasket.objects.create( + label=resulting_finds['basket_name'], user=user.ishtaruser) + for item in new_items: + b.items.add(item) + def save(self, *args, **kwargs): items, user, extra_args_for_new, resulting_find = [], None, [], None - upstream_items = [] + upstream_items, upstream_item, resulting_finds = [], None, None if "items" in kwargs: items = kwargs.pop('items') if "resulting_find" in kwargs: resulting_find = kwargs.pop('resulting_find') + if "resulting_finds" in kwargs: + resulting_finds = kwargs.pop('resulting_finds') if "upstream_items" in kwargs: upstream_items = kwargs.pop('upstream_items') + if "upstream_item" in kwargs: + upstream_item = kwargs.pop('upstream_item') if "user" in kwargs: user = kwargs.pop('user') if "extra_args_for_new" in kwargs: @@ -386,7 +421,12 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, upstream_items = upstream_items.items.all() if upstream_items and resulting_find: - self._create_resulting_find(resulting_find, upstream_items) + self._create_n_1_resulting_find(resulting_find, upstream_items) + return + + if upstream_item and resulting_finds: + self._create_1_n_resulting_find(resulting_finds, upstream_item, + self.history_modifier) return tps = list(self.treatment_types.all()) diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py index b9f4d8b6c..6e9f59b8c 100644 --- a/archaeological_finds/urls.py +++ b/archaeological_finds/urls.py @@ -106,6 +106,9 @@ urlpatterns = [ url(r'^treatment_creation_n1/(?P<step>.+)?$', check_rights(['change_find', 'change_own_find'])( views.treatment_creation_n1_wizard), name='treatment_creation_n1'), + url(r'^treatment_creation_1n/(?P<step>.+)?$', + check_rights(['change_find', 'change_own_find'])( + views.treatment_creation_1n_wizard), name='treatment_creation_1n'), url(r'^treatment_modification/(?P<step>.+)?$', check_rights(['change_find', 'change_own_find'])( diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index ceb00d432..29f0f75af 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -476,6 +476,19 @@ treatment_creation_n1_wizard = TreatmentN1Wizard.as_view( 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), + ('final-treatment_creation_1n', FinalForm) +] + +treatment_creation_1n_wizard = 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), diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py index 3c25258a6..bd16a55de 100644 --- a/archaeological_finds/wizards.py +++ b/archaeological_finds/wizards.py @@ -17,8 +17,9 @@ # See the file COPYING for details. +from django.contrib import messages from django.core.exceptions import ObjectDoesNotExist, PermissionDenied -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, pgettext from ishtar_common.forms import reverse_lazy from ishtar_common.wizards import Wizard, DeletionWizard, SearchWizard @@ -316,6 +317,70 @@ class TreatmentN1Wizard(TreatmentBase): return dct +class Treatment1NWizard(TreatmentBase): + saved_args = {"upstream_item": None, "resulting_finds": None} + base_url = 'treatment_creation_1n' + + def get_form_kwargs(self, step, **kwargs): + kwargs = super(Treatment1NWizard, self).get_form_kwargs(step, **kwargs) + if step != 'resultingfind-treatment_creation_1n': + return kwargs + kwargs['user'] = self.request.user + return kwargs + + def get_form_initial(self, step, data=None): + initial = super(Treatment1NWizard, self).get_form_initial(step) + if step != 'resultingfinds-treatment_creation_1n': + return initial + finds = self.get_current_finds() + if not finds: + return initial + lbl = finds[0].label + initial['resultings_basket_name'] = unicode(_(u"Basket")) + u" - " + lbl + initial['resultings_label'] = lbl + u"-" + return initial + + def get_extra_model(self, dct, form_list): + """ + Get items concerned by the treatment + """ + dct = super(Treatment1NWizard, self).get_extra_model(dct, form_list) + if 'resulting_pk' not in dct: + return dct + + # manage upstream item + pk = dct.pop('resulting_pk') + try: + find = models.Find.objects.get(pk=pk) + dct['upstream_item'] = find + except models.Find.DoesNotExist: + raise PermissionDenied + + if 'own' in self.current_right \ + and not find.is_own(dct['history_modifier']): + raise PermissionDenied + + # extract attributes to generate the new find + dct['resulting_finds'] = {} + for k in dct.keys(): + if k.startswith('resultings_'): + dct['resulting_finds'][ + k[len('resultings_'):] + ] = dct.pop(k) + messages.add_message( + self.request, messages.INFO, + unicode(_(u"The new basket: \"{}\" have been created with the " + 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"]) + self.request.session['find'] = '' + return dct + + class TreatmentDeletionWizard(DeletionWizard): model = models.Treatment fields = ['label', 'other_reference', 'year', 'index', |